summaryrefslogtreecommitdiff
path: root/engine/src/util.rs
blob: 532bdee010d6eda9140a580741464d82905aa0d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
macro_rules! try_option {
    ($expr: expr) => {
        match $expr {
            Ok(value) => value,
            Err(err) => {
                return Some(Err(err.into()));
            }
        }
    };
}

pub(crate) use try_option;

macro_rules! or {
    (($($tt: tt)+) else ($($else_tt: tt)*)) => {
        $($tt)+
    };

    (() else ($($else_tt: tt)*)) => {
        $($else_tt)*
    };
}

pub(crate) use or;

macro_rules! builder {
    (
        $(#[doc = $doc: literal])*
        #[builder(
            name = $builder_name: ident
            $(, derives = ($($builder_derive: ident),+))?
        )]
        $(#[$attr: meta])*
        $visibility: vis struct $name: ident
        {
            $(
                $(#[$field_attr: meta])*
                $field_visibility: vis $field: ident: $field_type: ty,
            )*
        }
    ) => {
        $(#[doc = $doc])*
        $(#[$attr])*
        $visibility struct $name
        {
            $(
                $(#[$field_attr])*
                $field_visibility $field: $field_type,
            )*
        }

        $(#[derive($($builder_derive),+)])?
        $visibility struct $builder_name
        {
            $(
                $field: $field_type,
            )*
        }

        impl $builder_name
        {
            $(
                #[must_use]
                $visibility fn $field(mut self, $field: $field_type) -> Self
                {
                    self.$field = $field;
                    self
                }
            )*

            #[must_use]
            $visibility fn build(self) -> $name {
                $name {
                    $(
                        $field: self.$field,
                    )*
                }
            }
        }

        impl From<$name> for $builder_name
        {
            fn from(built: $name) -> Self
            {
                Self {
                    $(
                        $field: built.$field,
                    )*
                }
            }
        }
    };
}

pub(crate) use builder;