domain_core/bits/opt/
rfc6975.rs1use std::slice;
4use bytes::{BufMut, Bytes};
5use ::bits::compose::Compose;
6use ::bits::message_builder::OptBuilder;
7use ::bits::parse::{ParseAll, Parser, ShortBuf};
8use ::iana::{OptionCode, SecAlg};
9use super::CodeOptData;
10
11
12macro_rules! option_type {
15 ( $name:ident ) => {
16 #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
17 pub struct $name {
18 bytes: Bytes,
19 }
20
21 impl $name {
22
23 pub fn from_bytes(bytes: Bytes) -> Self {
24 $name { bytes }
25 }
26
27 pub fn iter(&self) -> SecAlgsIter {
28 SecAlgsIter::new(self.bytes.as_ref())
29 }
30
31 pub fn push(builder: &mut OptBuilder, algs: &[SecAlg])
32 -> Result<(), ShortBuf> {
33 assert!(algs.len() <= ::std::u16::MAX as usize);
34 builder.build(OptionCode::$name, algs.len() as u16, |buf| {
35 for alg in algs {
36 buf.compose(&alg.to_int())?
37 }
38 Ok(())
39 })
40 }
41 }
42
43 impl ParseAll for $name {
46 type Err = ShortBuf;
47
48 fn parse_all(parser: &mut Parser, len: usize)
49 -> Result<Self, Self::Err> {
50 parser.parse_bytes(len).map(Self::from_bytes)
51 }
52 }
53
54 impl Compose for $name {
55 fn compose_len(&self) -> usize {
56 self.bytes.len()
57 }
58
59 fn compose<B: BufMut>(&self, buf: &mut B) {
60 buf.put_slice(self.bytes.as_ref())
61 }
62 }
63
64
65 impl CodeOptData for $name {
68 const CODE: OptionCode = OptionCode::$name;
69 }
70
71
72 impl<'a> IntoIterator for &'a $name {
75 type Item = SecAlg;
76 type IntoIter = SecAlgsIter<'a>;
77
78 fn into_iter(self) -> Self::IntoIter {
79 self.iter()
80 }
81 }
82 }
83}
84
85option_type!(Dau);
86option_type!(Dhu);
87option_type!(N3u);
88
89
90pub struct SecAlgsIter<'a>(slice::Iter<'a, u8>);
93
94impl<'a> SecAlgsIter<'a> {
95 fn new(slice: &'a [u8]) -> Self {
96 SecAlgsIter(slice.iter())
97 }
98}
99
100impl<'a> Iterator for SecAlgsIter<'a> {
101 type Item = SecAlg;
102
103 fn next(&mut self) -> Option<Self::Item> {
104 self.0.next().map(|x| SecAlg::from_int(*x))
105 }
106}