Skip to content

Instantly share code, notes, and snippets.

@SpencerSharkey
Created August 6, 2023 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpencerSharkey/352f1f5347812f8784ecfc4a97878a42 to your computer and use it in GitHub Desktop.
Save SpencerSharkey/352f1f5347812f8784ecfc4a97878a42 to your computer and use it in GitHub Desktop.
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