simple_dns/dns/rdata/
isdn.rs

1use std::collections::HashMap;
2
3use crate::dns::{name::Label, CharacterString, WireFormat};
4
5use super::RR;
6
7/// An ISDN (Integrated Service Digital Network) number is simply a telephone number.
8#[derive(Debug, PartialEq, Eq, Hash, Clone)]
9pub struct ISDN<'a> {
10    /// A [CharacterString](`CharacterString`) which specifies the address.
11    pub address: CharacterString<'a>,
12    /// A [CharacterString](`CharacterString`) which specifies the subaddress.
13    pub sa: CharacterString<'a>,
14}
15
16impl<'a> RR for ISDN<'a> {
17    const TYPE_CODE: u16 = 20;
18}
19
20impl<'a> ISDN<'a> {
21    /// Transforms the inner data into its owned type
22    pub fn into_owned<'b>(self) -> ISDN<'b> {
23        ISDN {
24            address: self.address.into_owned(),
25            sa: self.sa.into_owned(),
26        }
27    }
28}
29
30impl<'a> WireFormat<'a> for ISDN<'a> {
31    fn parse(data: &'a [u8], position: &mut usize) -> crate::Result<Self>
32    where
33        Self: Sized,
34    {
35        let address = CharacterString::parse(data, position)?;
36        let sa = CharacterString::parse(data, position)?;
37
38        Ok(Self { address, sa })
39    }
40
41    fn write_to<T: std::io::Write>(&self, out: &mut T) -> crate::Result<()> {
42        self.address.write_to(out)?;
43        self.sa.write_to(out)
44    }
45
46    fn write_compressed_to<T: std::io::Write + std::io::Seek>(
47        &'a self,
48        out: &mut T,
49        name_refs: &mut HashMap<&'a [Label<'a>], usize>,
50    ) -> crate::Result<()> {
51        self.address.write_compressed_to(out, name_refs)?;
52        self.sa.write_compressed_to(out, name_refs)
53    }
54
55    fn len(&self) -> usize {
56        self.address.len() + self.sa.len()
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use crate::{rdata::RData, ResourceRecord};
63
64    use super::*;
65
66    #[test]
67    fn parse_and_write_isdn() {
68        let isdn = ISDN {
69            address: CharacterString::new(b"150862028003217").unwrap(),
70            sa: CharacterString::new(b"004").unwrap(),
71        };
72
73        let mut data = Vec::new();
74        assert!(isdn.write_to(&mut data).is_ok());
75
76        let isdn = ISDN::parse(&data, &mut 0);
77        assert!(isdn.is_ok());
78        let isdn = isdn.unwrap();
79
80        assert_eq!(data.len(), isdn.len());
81        assert_eq!("150862028003217", isdn.address.to_string());
82        assert_eq!("004", isdn.sa.to_string());
83    }
84
85    #[test]
86    fn parse_sample() -> Result<(), Box<dyn std::error::Error>> {
87        let sample_file = std::fs::read("samples/zonefile/ISDN.sample")?;
88
89        let sample_rdata = match ResourceRecord::parse(&sample_file, &mut 0)?.rdata {
90            RData::ISDN(rdata) => rdata,
91            _ => unreachable!(),
92        };
93
94        assert_eq!(sample_rdata.address, "isdn-address".try_into()?);
95        assert_eq!(sample_rdata.sa, "subaddress".try_into()?);
96        Ok(())
97    }
98}