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        $( pub mod $module; )*
16
17        //------------ AllOptData --------------------------------------------
18
19        // TODO Impl Debug.
20        #[derive(Clone)]
21        #[non_exhaustive]
22        pub enum AllOptData<Octs, Name> {
23            $( $(
24                $opt($module::$opt $( < $( $octets ),* > )? ),
25            )* )*
26            Other(UnknownOptData<Octs>),
27        }
28
29        //--- From
30
31        $( $(
32            impl<Octs, Name> From<$opt $( < $( $octets> ),* )?>
33            for AllOptData<Octs, Name> {
34                fn from(
35                    value: $module::$opt$( < $( $octets ),* > )*
36                ) -> Self {
37                    AllOptData::$opt(value)
38                }
39            }
40        )* )*
41
42        //--- OptData
43
44        impl<Octs, Name> OptData for AllOptData<Octs, Name> {
45            fn code(&self) -> OptionCode {
46                match *self {
47                    $( $(
48                        AllOptData::$opt(_) => OptionCode::$opt,
49                    )* )*
50                    AllOptData::Other(ref inner) => inner.code(),
51                }
52            }
53        }
54
55        impl<'a, Octs: Octets> ParseOptData<'a, Octs>
56        for AllOptData<Octs::Range<'a>, Dname<Octs::Range<'a>>> {
57            fn parse_option(
58                code: OptionCode,
59                parser: &mut Parser<'a, Octs>,
60            ) -> Result<Option<Self>, ParseError> {
61                match code {
62                    $( $(
63                        OptionCode::$opt => {
64                            Ok(Some(AllOptData::$opt(
65                                $opt::parse(parser)?
66                            )))
67                        }
68                    )* )*
69                    _ => {
70                        Ok(UnknownOptData::parse_option(
71                            code, parser
72                        )?.map(AllOptData::Other))
73                    }
74                }
75            }
76        }
77
78        impl<Octs, Name> ComposeOptData for AllOptData<Octs, Name>
79        where Octs: AsRef<[u8]>, Name: ToDname {
80            fn compose_len(&self) -> u16 {
81                match *self {
82                    $( $(
83                        AllOptData::$opt(ref inner) => inner.compose_len(),
84                    )* )*
85                    AllOptData::Other(ref inner) => inner.compose_len(),
86                }
87            }
88
89            fn compose_option<Target: octseq::builder::OctetsBuilder + ?Sized>(
90                &self, target: &mut Target
91            ) -> Result<(), Target::AppendError> {
92                match *self {
93                    $( $(
94                        AllOptData::$opt(ref inner) => {
95                            inner.compose_option(target)
96                        }
97                    )* )*
98                    AllOptData::Other(ref inner) => {
99                        inner.compose_option(target)
100                    }
101                }
102            }
103        }
104    }
105}