How to write macros for these repeated codes?

I have the following hierarchy enums:

enum School {
    Class1(Class1),
    Class2(Class2),
} 

enum Class1 {}

enum Class2 {
    Block1(Block1),
    Block2(Block2),
}

enum Block1 {}

enum Block2 {
    Name1,
    Name2,
    Name3,
}

It has a structure like this:

School 
    Class1
        Block1
            Name1
            Name2
            Name3
            .//many of Name
            .
            .
        Block2
    Class2

I'am trying to write out every variant in Block1 like this:

const name1er: School = School::Class2(Class2::Block2(Block2::Name1));
const name2er: School = School::Class2(Class2::Block2(Block2::Name2));
const name3er: School = School::Class2(Class2::Block2(Block2::Name3));

The code seems redunctant. Is there a way a can define a macro or something to get the target automatically?

If you just want a macro that takes the final name it's pretty easy

Playground

#[derive(Debug)]
enum School {
    Class1(Class1),
    Class2(Class2),
}

#[derive(Debug)]
enum Class1 {}

#[derive(Debug)]
enum Class2 {
    Block1(Block1),
    Block2(Block2),
}

#[derive(Debug)]
enum Block1 {}

#[derive(Debug)]
enum Block2 {
    Name1,
    Name2,
    Name3,
}

macro_rules! name {
    ($name:ident) => {
        School::Class2(Class2::Block2(Block2::$name))
    };
}

fn main() {
    let name1er: School = name!(Name1);
    let name2er: School = name!(Name2);
    let name3er: School = name!(Name3);

    println!("{name1er:?}, {name2er:?}, {name3er:?}")
}
1 Like

Thanks for your reply. But if I also need the next to the final like this:

const name1er: School = School::Class2(Class2::Block1(Block1::Name1));
const name2er: School = School::Class2(Class2::Block1(Block1::Name2));
const name3er: School = School::Class2(Class2::Block1(Block1::Name3));

const name1er: School = School::Class2(Class2::Block2(Block2::Name1));
const name2er: School = School::Class2(Class2::Block2(Block2::Name2));
const name3er: School = School::Class2(Class2::Block2(Block2::Name3));

What should I do?

You can pretty easily tweak it if you only have 2 blocks. As the combinations grow it will be more of a pain to maintain

#[derive(Debug)]
enum School {
    Class1(Class1),
    Class2(Class2),
}

#[derive(Debug)]
enum Class1 {}

#[derive(Debug)]
enum Class2 {
    Block1(Block1),
    Block2(Block2),
}

#[derive(Debug)]
enum Block1 {
    Name1,
    Name2,
    Name3,
}

#[derive(Debug)]
enum Block2 {
    Name1,
    Name2,
    Name3,
}

macro_rules! name {
    (1, $name:ident) => {
        School::Class2(Class2::Block1(Block1::$name))
    };
    (2, $name:ident) => {
        School::Class2(Class2::Block2(Block2::$name))
    };
}

fn main() {
    let name1er: School = name!(1, Name1);
    let name2er: School = name!(1, Name2);
    let name3er: School = name!(1, Name3);

    println!("{name1er:?}, {name2er:?}, {name3er:?}");

    let name1er: School = name!(2, Name1);
    let name2er: School = name!(2, Name2);
    let name3er: School = name!(2, Name3);

    println!("{name1er:?}, {name2er:?}, {name3er:?}");
}
1 Like
use School::*;
use Class2::*;
const name1er: School = Class2(Block1(Block1::Name1));
const name2er: School = Class2(Block1(Block1::Name2));
const name3er: School = Class2(Block1(Block1::Name3));

const name1er: School = Class2(Block2(Block2::Name1));
const name2er: School = Class2(Block2(Block2::Name2));
const name3er: School = Class2(Block2(Block2::Name3));
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.