-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to wrap a pluckable HCons in a struct with outher fields? #221
Comments
...with a little bit of help from chatGPT, I ended up with this: use frunk::hlist::Plucker;
struct Mode;
struct GpioPin<MODE, const NUM: u8> {
_mode: PhantomData<MODE>,
}
impl<MODE, const NUM: u8> GpioPin<MODE, NUM> {
fn new() -> Self { Self { _mode: PhantomData } }
}
pub struct IO<H> {
_io_mux: (),
pub pins: H,
}
impl<H> IO<H> {
fn pluck_io<const NUM: u8, Remaining>(self) -> (GpioPin<Mode, NUM>, IO<H::Remainder>)
where
H: Plucker<GpioPin<Mode, NUM>, Remaining>,
{
let (pin, remaining_pins) = self.pins.pluck();
(pin, IO { _io_mux: self._io_mux, pins: remaining_pins })
}
}
#[macro_export]
macro_rules! create_pins {
($($gpionum:expr),+) => {
frunk::hlist![$(GpioPin::<Mode, $gpionum>::new()),+]
};
}
#[macro_export]
macro_rules! create_pin_hlist {
($($gpionum:expr),+) => {
frunk::HList![$(NumThing<Mode, { $gpionum }>),+]
};
}
fn main() {
let pins = create_pins!(0, 1, 2);
let io = IO {_io_mux: (), pins};
let (pin, pins) = io.pluck_io::<2, _>();
println!("Hello, world!");
} ...this compiles as I'm hoping, and when I get lsp to insert an explicit type on the let (pin, io): (GpioPin<Mode, 2>, IO<frunk::HCons<GpioPin<Mode, 0>, frunk::HCons<GpioPin<Mode, 1>, frunk::HNil>>>) = io.pluck_io::<2, _>(); ...which is exactly what I want! That's in a bare-bones project though. When |
...first of all, I must say this is amazing and I can't think of a better way to do it (I might suggest SO for finding the optimal solution). However, what is more interesting to me is somehow you got help from ChatGPT?? It's a completely tangential topic from your question that IMO deserves a call out of its own and can enable users of this lib to "learn how to learn how to fish". Can you please give some details as to how you did that? EDIT (submitted too quickly): Typically, for types that aren't themselves labelled with Frunk-derivation markers, indeed, things are tougher and I think some manual conversion to a custom type that you control might be required before you can do this kind magic, sadly, which also means having to write a converter back to that other type to interface with that lib. Concretely this means writing From/Tos. An alternative is to submit a PR to that lib, with some kind of optional |
Glad you like the solution! this is, in fact, intended to be an upstream commit to resolve partial-move issues when managing gpio pins for esp32 microcontrollers. You can see the initial draft of the PR here: esp-rs/esp-hal#748 To use chatGPT, I started a new chat (model 4):
Basically, I forwarded this post to chatGPT. Took a few iterations of feeding the errors back into the chat in order to get the pub struct IO<T>
where
T: for<const NUM: u8, Remaining> Plucker<GpioPin<Unknown, NUM>, Remaining>
{
_io_mux: IO_MUX,
pub pins: T
} I also have this in my custom instructions (new chatgpt feature):
The fish lesson, I guess, is: Start with a high-quality question (I spent quite a while working on this question. Never intended to post to chatGPT until after the post), (EDIT: fat-fingered submit) and to use it as a tool to help de-obfuscate the complexity to integrate it into your knowledge-base, rather than as a source of providing a solution. |
I would like to refactor this:
(A reduced version of the `Pins` struct:)
into this:
I've built macros to create the HList type and to construct an initial pin-list:
...and go from this:
to something like this:
And `Blinker` might look something like this:
Setting up the IO struct is difficult:
Plucker
forIO
?Plucker
in such a way that aconst NUM: u8
can be used, and pluck solely based on the GpioNums const?HCons
from the ground up, copy-pasting a lot of the code? Is there a way I'd be able to re-use thefrunk
implementations (e.g. by setting the pins field to beHCons<???, ???>
)?usbd-human-interface-device
, but that doesn't take advantage of plucking (which is a core feature I'm after)The text was updated successfully, but these errors were encountered: