domain/base/opt/
macros.rs

1//! Macros for option types.
2//!
3//! These macros are only used to generate enums in the parent module.
4//! They are here in a separate module to keep the parent tidy.
5
6macro_rules! opt_types {
7    ( $(
8        $module:ident::{
9            $( $opt:ident $( < $( $octets:ident ),* > )? ),*
10        };
11    )* ) => {
12
13        $( $( pub use self::$module::$opt; )* )*
14
15        //------------ AllOptData --------------------------------------------
16
17        #[derive(Clone)]
18        #[cfg_attr(
19            feature = "serde",
20            derive(serde::Serialize),
21            serde(bound(
22                serialize = "
23                    Octs: AsRef<[u8]> + octseq::serde::SerializeOctets,
24                    Name: serde::Serialize,
25                ",
26            ))
27        )]
28        #[non_exhaustive]
29        pub enum AllOptData<Octs, Name> {
30            $( $(
31                $opt($module::$opt $( < $( $octets ),* > )? ),
32            )* )*
33            Other(UnknownOptData<Octs>),
34        }
35
36        //--- OctetsFrom
37
38        impl<Octs, Name, SrcOcts, SrcName>
39        OctetsFrom<AllOptData<SrcOcts, SrcName>>
40        for AllOptData<Octs, Name>
41        where
42            Octs: OctetsFrom<SrcOcts>,
43            Name: OctetsFrom<SrcName, Error = Octs::Error>,
44        {
45            type Error = Octs::Error;
46
47            fn try_octets_from(
48                source: AllOptData<SrcOcts, SrcName>,
49            ) -> Result<Self, Self::Error> {
50                match source {
51                    $( $(
52                        AllOptData::$opt(opt) => {
53                            Ok(AllOptData::$opt(
54                                $module::$opt::try_octets_from(opt)?
55                            ))
56                        },
57                    )* )*
58                    AllOptData::Other(opt) => {
59                        Ok(AllOptData::Other(
60                            UnknownOptData::try_octets_from(opt)?
61                        ))
62                    }
63                }
64            }
65        }
66
67        //--- From
68
69        $( $(
70            impl<Octs, Name> From<$opt $( < $( $octets> ),* )?>
71            for AllOptData<Octs, Name> {
72                fn from(
73                    value: $module::$opt$( < $( $octets ),* > )*
74                ) -> Self {
75                    AllOptData::$opt(value)
76                }
77            }
78        )* )*
79
80        //--- OptData
81
82        impl<Octs, Name> OptData for AllOptData<Octs, Name> {
83            fn code(&self) -> OptionCode {
84                match *self {
85                    $( $(
86                        AllOptData::$opt(_) => $module::$opt::CODE,
87                    )* )*
88                    AllOptData::Other(ref inner) => inner.code(),
89                }
90            }
91        }
92
93        impl<'a, Octs: Octets> ParseOptData<'a, Octs>
94        for AllOptData<Octs::Range<'a>, Name<Octs::Range<'a>>> {
95            fn parse_option(
96                code: OptionCode,
97                parser: &mut Parser<'a, Octs>,
98            ) -> Result<Option<Self>, ParseError> {
99                match code {
100                    $( $(
101                        $module::$opt::CODE => {
102                            Ok(Some(AllOptData::$opt(
103                                $opt::parse(parser)?
104                            )))
105                        }
106                    )* )*
107                    _ => {
108                        Ok(UnknownOptData::parse_option(
109                            code, parser
110                        )?.map(AllOptData::Other))
111                    }
112                }
113            }
114        }
115
116        impl<Octs, Name> ComposeOptData for AllOptData<Octs, Name>
117        where Octs: AsRef<[u8]>, Name: ToName {
118            fn compose_len(&self) -> u16 {
119                match *self {
120                    $( $(
121                        AllOptData::$opt(ref inner) => inner.compose_len(),
122                    )* )*
123                    AllOptData::Other(ref inner) => inner.compose_len(),
124                }
125            }
126
127            fn compose_option<Target: octseq::builder::OctetsBuilder + ?Sized>(
128                &self, target: &mut Target
129            ) -> Result<(), Target::AppendError> {
130                match *self {
131                    $( $(
132                        AllOptData::$opt(ref inner) => {
133                            inner.compose_option(target)
134                        }
135                    )* )*
136                    AllOptData::Other(ref inner) => {
137                        inner.compose_option(target)
138                    }
139                }
140            }
141        }
142
143        //--- Debug
144
145        impl<Octs, Name> fmt::Debug for AllOptData<Octs, Name>
146        where Octs: AsRef<[u8]>, Name: fmt::Display {
147            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148                match *self {
149                    $( $(
150                        AllOptData::$opt(ref inner) => {
151                            fmt::Debug::fmt(inner, f)
152                        }
153                    )* )*
154                    AllOptData::Other(ref inner) => {
155                            fmt::Debug::fmt(inner, f)
156                    }
157                }
158            }
159        }
160    }
161}