Created
August 6, 2023 02:00
-
-
Save SpencerSharkey/352f1f5347812f8784ecfc4a97878a42 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() {} | |
// just some fake structs | |
#[derive(Debug)] | |
pub struct Zebra { | |
name: &'static str, | |
} | |
#[derive(Debug)] | |
pub struct Dog { | |
name: &'static str, | |
} | |
#[derive(Debug)] | |
pub struct Tiger { | |
name: &'static str, | |
} | |
#[derive(Debug)] | |
pub struct Cat { | |
name: &'static str, | |
} | |
// some enum variant to match on, i guess | |
pub enum Animal { | |
Zebra(Zebra), | |
Dog(Dog), | |
Tiger(Tiger), | |
Cat(Cat), | |
} | |
// my macro | |
macro_rules! builder { | |
($iter:ident, $($field:tt = $variant:path),*) => { | |
{ | |
$( | |
let mut $field = None; | |
)* | |
for item in $iter { | |
match item { | |
$($variant(inner) => { | |
$field.replace(inner); | |
})* | |
#[allow(unreachable_patterns)] | |
_ => { | |
// if we see unexpected item, do nothing i guess? | |
} | |
} | |
} | |
Self { | |
$($field,)* | |
} | |
} | |
}; | |
} | |
// my thing containig struct fields for all these things | |
#[derive(Debug)] | |
pub struct NoahsArk { | |
zebra: Option<Zebra>, | |
dog: Option<Dog>, | |
tiger: Option<Tiger>, | |
cat: Option<Cat>, | |
} | |
impl NoahsArk { | |
pub fn populate(passengers: impl Iterator<Item = Animal>) -> Self { | |
builder!( | |
passengers, | |
zebra = Animal::Zebra, | |
dog = Animal::Dog, | |
tiger = Animal::Tiger, | |
cat = Animal::Cat | |
) | |
} | |
} | |
#[derive(Debug)] | |
pub struct DomesticArk { | |
dog: Option<Dog>, | |
cat: Option<Cat>, | |
} | |
impl DomesticArk { | |
pub fn populate(passengers: impl Iterator<Item = Animal>) -> Self { | |
builder!(passengers, dog = Animal::Dog, cat = Animal::Cat) | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
#[test] | |
fn test() { | |
let source1 = vec![ | |
Animal::Cat(Cat { name: "scruffy" }), | |
Animal::Dog(Dog { name: "spot" }), | |
]; | |
let ark1 = DomesticArk::populate(source1.into_iter()); | |
dbg!(ark1); | |
let source2 = vec![ | |
Animal::Cat(Cat { name: "scruffy" }), | |
Animal::Dog(Dog { name: "spot" }), | |
Animal::Zebra(Zebra { name: "stripes" }), | |
]; | |
let ark2 = NoahsArk::populate(source2.into_iter()); | |
dbg!(ark2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment