1use std::{fmt, ops};
8use std::net::Ipv4Addr;
9use std::str::FromStr;
10use bytes::{BufMut, Bytes, BytesMut};
11use ::iana::Rtype;
12use ::bits::charstr::CharStr;
13use ::bits::compose::{Compose, Compress, Compressor};
14use ::bits::name::ParsedDname;
15use ::bits::parse::{ParseAll, ParseAllError, ParseOpenError, Parse,
16 Parser, ShortBuf};
17use ::bits::rdata::RtypeRecordData;
18use ::bits::serial::Serial;
19use ::master::scan::{CharSource, ScanError, Scan, Scanner};
20
21
22macro_rules! dname_type {
29 ($target:ident, $rtype:ident, $field:ident) => {
30 #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
31 pub struct $target<N> {
32 $field: N
33 }
34
35 impl<N> $target<N> {
36 pub fn new($field: N) -> Self {
37 $target { $field: $field }
38 }
39
40 pub fn $field(&self) -> &N {
41 &self.$field
42 }
43 }
44
45 impl<N> From<N> for $target<N> {
48 fn from(name: N) -> Self {
49 Self::new(name)
50 }
51 }
52
53 impl<N: FromStr> FromStr for $target<N> {
54 type Err = N::Err;
55
56 fn from_str(s: &str) -> Result<Self, Self::Err> {
57 N::from_str(s).map(Self::new)
58 }
59 }
60
61
62 impl Parse for $target<ParsedDname> {
65 type Err = <ParsedDname as Parse>::Err;
66
67 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
68 ParsedDname::parse(parser).map(Self::new)
69 }
70
71 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
72 ParsedDname::skip(parser).map_err(Into::into)
73 }
74 }
75
76 impl ParseAll for $target<ParsedDname> {
77 type Err = <ParsedDname as ParseAll>::Err;
78
79 fn parse_all(parser: &mut Parser, len: usize)
80 -> Result<Self, Self::Err> {
81 ParsedDname::parse_all(parser, len).map(Self::new)
82 }
83 }
84
85 impl<N: Compose> Compose for $target<N> {
86 fn compose_len(&self) -> usize {
87 self.$field.compose_len()
88 }
89
90 fn compose<B: BufMut>(&self, buf: &mut B) {
91 self.$field.compose(buf)
92 }
93 }
94
95 impl<N: Compress> Compress for $target<N> {
96 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
97 self.$field.compress(buf)
98 }
99 }
100
101
102 impl<N: Scan> Scan for $target<N> {
105 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
106 -> Result<Self, ScanError> {
107 N::scan(scanner).map(Self::new)
108 }
109 }
110
111 impl<N: fmt::Display> fmt::Display for $target<N> {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 write!(f, "{}.", self.$field)
114 }
115 }
116
117
118 impl<N> RtypeRecordData for $target<N> {
121 const RTYPE: Rtype = Rtype::$rtype;
122 }
123
124
125 impl<N> ops::Deref for $target<N> {
128 type Target = N;
129
130 fn deref(&self) -> &Self::Target {
131 &self.$field
132 }
133 }
134 }
135}
136
137
138#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
148pub struct A {
149 addr: Ipv4Addr,
150}
151
152impl A {
153 pub fn new(addr: Ipv4Addr) -> A {
155 A { addr }
156 }
157
158 pub fn from_octets(a: u8, b: u8, c: u8, d: u8) -> A {
160 A::new(Ipv4Addr::new(a, b, c, d))
161 }
162
163 pub fn addr(&self) -> Ipv4Addr { self.addr }
164 pub fn set_addr(&mut self, addr: Ipv4Addr) { self.addr = addr }
165}
166
167
168impl From<Ipv4Addr> for A {
171 fn from(addr: Ipv4Addr) -> Self {
172 Self::new(addr)
173 }
174}
175
176impl From<A> for Ipv4Addr {
177 fn from(a: A) -> Self {
178 a.addr
179 }
180}
181
182impl FromStr for A {
183 type Err = <Ipv4Addr as FromStr>::Err;
184
185 fn from_str(s: &str) -> Result<Self, Self::Err> {
186 Ipv4Addr::from_str(s).map(A::new)
187 }
188}
189
190
191impl Parse for A {
194 type Err = <Ipv4Addr as Parse>::Err;
195
196 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
197 Ipv4Addr::parse(parser).map(Self::new)
198 }
199
200 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
201 Ipv4Addr::skip(parser)?;
202 Ok(())
203 }
204}
205
206impl ParseAll for A {
207 type Err = <Ipv4Addr as ParseAll>::Err;
208
209 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
210 Ipv4Addr::parse_all(parser, len).map(Self::new)
211 }
212}
213
214impl Compose for A {
215 fn compose_len(&self) -> usize {
216 4
217 }
218
219 fn compose<B: BufMut>(&self, buf: &mut B) {
220 self.addr.compose(buf)
221 }
222}
223
224impl Compress for A {
225 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
226 buf.compose(self)
227 }
228}
229
230
231impl Scan for A {
234 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
235 -> Result<Self, ScanError> {
236 scanner.scan_string_phrase(|res| A::from_str(&res).map_err(Into::into))
237 }
238}
239
240impl fmt::Display for A {
241 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
242 self.addr.fmt(f)
243 }
244}
245
246
247impl RtypeRecordData for A {
250 const RTYPE: Rtype = Rtype::A;
251}
252
253
254impl ops::Deref for A {
257 type Target = Ipv4Addr;
258
259 fn deref(&self) -> &Self::Target {
260 &self.addr
261 }
262}
263
264impl ops::DerefMut for A {
265 fn deref_mut(&mut self) -> &mut Self::Target {
266 &mut self.addr
267 }
268}
269
270
271impl AsRef<Ipv4Addr> for A {
274 fn as_ref(&self) -> &Ipv4Addr {
275 &self.addr
276 }
277}
278
279impl AsMut<Ipv4Addr> for A {
280 fn as_mut(&mut self) -> &mut Ipv4Addr {
281 &mut self.addr
282 }
283}
284
285
286dname_type!(Cname, Cname, cname);
295
296
297#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
306pub struct Hinfo {
307 cpu: CharStr,
308 os: CharStr,
309}
310
311impl Hinfo {
312 pub fn new(cpu: CharStr, os: CharStr) -> Self {
314 Hinfo { cpu, os }
315 }
316
317 pub fn cpu(&self) -> &CharStr {
319 &self.cpu
320 }
321
322 pub fn os(&self) -> &CharStr {
324 &self.os
325 }
326}
327
328impl Parse for Hinfo {
331 type Err = ShortBuf;
332
333 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
334 Ok(Self::new(CharStr::parse(parser)?, CharStr::parse(parser)?))
335 }
336
337 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
338 CharStr::skip(parser)?;
339 CharStr::skip(parser)?;
340 Ok(())
341 }
342}
343
344impl ParseAll for Hinfo {
345 type Err = ParseAllError;
346
347 fn parse_all(parser: &mut Parser, len: usize)
348 -> Result<Self, Self::Err> {
349 let cpu = CharStr::parse(parser)?;
350 let len = match len.checked_sub(cpu.len() + 1) {
351 Some(len) => len,
352 None => return Err(ParseAllError::ShortField)
353 };
354 let os = CharStr::parse_all(parser, len)?;
355 Ok(Hinfo::new(cpu, os))
356 }
357}
358
359impl Compose for Hinfo {
360 fn compose_len(&self) -> usize {
361 self.cpu.compose_len() + self.os.compose_len()
362 }
363
364 fn compose<B: BufMut>(&self, buf: &mut B) {
365 self.cpu.compose(buf);
366 self.os.compose(buf);
367 }
368}
369
370impl Compress for Hinfo {
371 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
372 buf.compose(self)
373 }
374}
375
376
377impl Scan for Hinfo {
380 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
381 -> Result<Self, ScanError> {
382 Ok(Self::new(CharStr::scan(scanner)?, CharStr::scan(scanner)?))
383 }
384}
385
386impl fmt::Display for Hinfo {
387 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
388 write!(f, "{} {}", self.cpu, self.os)
389 }
390}
391
392
393impl RtypeRecordData for Hinfo {
396 const RTYPE: Rtype = Rtype::Hinfo;
397}
398
399
400dname_type!(Mb, Mb, madname);
408
409
410dname_type!(Md, Md, madname);
422
423
424dname_type!(Mf, Mf, madname);
436
437
438dname_type!(Mg, Mg, madname);
449
450
451#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
463pub struct Minfo<N=ParsedDname> {
464 rmailbx: N,
465 emailbx: N,
466}
467
468impl<N> Minfo<N> {
469 pub fn new(rmailbx: N, emailbx: N) -> Self {
471 Minfo { rmailbx, emailbx }
472 }
473
474 pub fn rmailbx(&self) -> &N {
480 &self.rmailbx
481 }
482
483 pub fn emailbx(&self) -> &N {
490 &self.emailbx
491 }
492}
493
494
495impl<N: Parse> Parse for Minfo<N> {
498 type Err = N::Err;
499
500 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
501 Ok(Self::new(N::parse(parser)?, N::parse(parser)?))
502 }
503
504 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
505 N::skip(parser)?;
506 N::skip(parser)?;
507 Ok(())
508 }
509}
510
511impl<N: Parse + ParseAll> ParseAll for Minfo<N>
512 where <N as ParseAll>::Err: From<<N as Parse>::Err> + From<ShortBuf> {
513 type Err = <N as ParseAll>::Err;
514
515 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
516 let pos = parser.pos();
517 let rmailbx = N::parse(parser)?;
518 let rlen = parser.pos() - pos;
519 let len = if len <= rlen {
520 parser.seek(pos)?;
523 0
524 }
525 else {
526 len - rlen
527 };
528 let emailbx = N::parse_all(parser, len)?;
529 Ok(Self::new(rmailbx, emailbx))
530 }
531}
532
533impl<N: Compose> Compose for Minfo<N> {
534 fn compose_len(&self) -> usize {
535 self.rmailbx.compose_len() + self.emailbx.compose_len()
536 }
537
538 fn compose<B: BufMut>(&self, buf: &mut B) {
539 self.rmailbx.compose(buf);
540 self.emailbx.compose(buf);
541 }
542}
543
544impl<N: Compress> Compress for Minfo<N> {
545 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
546 self.rmailbx.compress(buf)?;
547 self.emailbx.compress(buf)
548 }
549}
550
551
552impl<N: Scan> Scan for Minfo<N> {
555 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
556 -> Result<Self, ScanError> {
557 Ok(Self::new(N::scan(scanner)?, N::scan(scanner)?))
558 }
559}
560
561impl<N: fmt::Display> fmt::Display for Minfo<N> {
562 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
563 write!(f, "{}. {}.", self.rmailbx, self.emailbx)
564 }
565}
566
567
568impl<N> RtypeRecordData for Minfo<N> {
571 const RTYPE: Rtype = Rtype::Minfo;
572}
573
574
575dname_type!(Mr, Mr, newname);
586
587
588#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
597pub struct Mx<N=ParsedDname> {
598 preference: u16,
599 exchange: N,
600}
601
602impl<N> Mx<N> {
603 pub fn new(preference: u16, exchange: N) -> Self {
605 Mx { preference, exchange }
606 }
607
608 pub fn preference(&self) -> u16 {
613 self.preference
614 }
615
616 pub fn exchange(&self) -> &N {
618 &self.exchange
619 }
620}
621
622
623impl<N: Parse> Parse for Mx<N>
626 where N::Err: From<ShortBuf> {
627 type Err = N::Err;
628
629 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
630 Ok(Self::new(u16::parse(parser)?, N::parse(parser)?))
631 }
632
633 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
634 u16::skip(parser)?;
635 N::skip(parser)
636 }
637}
638
639impl<N: ParseAll> ParseAll for Mx<N>
640 where N::Err: From<ParseOpenError> + From<ShortBuf> {
641 type Err = N::Err;
642
643 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
644 if len < 3 {
645 return Err(ParseOpenError::ShortField.into())
646 }
647 Ok(Self::new(u16::parse(parser)?, N::parse_all(parser, len - 2)?))
648 }
649}
650
651impl<N: Compose> Compose for Mx<N> {
652 fn compose_len(&self) -> usize {
653 self.exchange.compose_len() + 2
654 }
655
656 fn compose<B: BufMut>(&self, buf: &mut B) {
657 self.preference.compose(buf);
658 self.exchange.compose(buf);
659 }
660}
661
662impl<N: Compress> Compress for Mx<N> {
663 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
664 buf.compose(&self.preference)?;
665 self.exchange.compress(buf)
666 }
667}
668
669
670impl<N: Scan> Scan for Mx<N> {
673 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
674 -> Result<Self, ScanError> {
675 Ok(Self::new(u16::scan(scanner)?, N::scan(scanner)?))
676 }
677}
678
679impl<N: fmt::Display> fmt::Display for Mx<N> {
680 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
681 write!(f, "{} {}.", self.preference, self.exchange)
682 }
683}
684
685
686impl<N> RtypeRecordData for Mx<N> {
689 const RTYPE: Rtype = Rtype::Mx;
690}
691
692
693dname_type!(Ns, Ns, nsdname);
701
702
703#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
712pub struct Null {
713 data: Bytes,
714}
715
716impl Null {
717 pub fn new(data: Bytes) -> Self {
719 Null { data }
720 }
721
722 pub fn data(&self) -> &Bytes {
724 &self.data
725 }
726}
727
728
729impl From<Bytes> for Null {
732 fn from(data: Bytes) -> Self {
733 Self::new(data)
734 }
735}
736
737
738impl ParseAll for Null {
741 type Err = ShortBuf;
742
743 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
744 parser.parse_bytes(len).map(Self::new)
745 }
746}
747
748impl Compose for Null {
749 fn compose_len(&self) -> usize {
750 self.data.len()
751 }
752
753 fn compose<B: BufMut>(&self, buf: &mut B) {
754 buf.put_slice(self.data.as_ref())
755 }
756}
757
758impl Compress for Null {
759 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
760 buf.compose(self)
761 }
762}
763
764
765impl RtypeRecordData for Null {
768 const RTYPE: Rtype = Rtype::Null;
769}
770
771
772impl ops::Deref for Null {
775 type Target = Bytes;
776
777 fn deref(&self) -> &Self::Target {
778 &self.data
779 }
780}
781
782
783impl AsRef<Bytes> for Null {
786 fn as_ref(&self) -> &Bytes {
787 &self.data
788 }
789}
790
791impl AsRef<[u8]> for Null {
792 fn as_ref(&self) -> &[u8] {
793 self.data.as_ref()
794 }
795}
796
797
798impl fmt::Display for Null {
801 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
802 write!(f, "\\# {}", self.data().len())?;
803 for ch in self.data().iter() {
804 write!(f, " {:02x}", ch)?;
805 }
806 Ok(())
807 }
808}
809
810
811dname_type!(Ptr, Ptr, ptrdname);
820
821impl<N> Ptr<N> {
822 pub fn into_ptrdname(self) -> N {
823 self.ptrdname
824 }
825}
826
827
828#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd)]
837pub struct Soa<N=ParsedDname> {
838 mname: N,
839 rname: N,
840 serial: Serial,
841 refresh: u32,
842 retry: u32,
843 expire: u32,
844 minimum:u32
845}
846
847impl<N> Soa<N> {
848 pub fn new(mname: N, rname: N, serial: Serial,
850 refresh: u32, retry: u32, expire: u32, minimum: u32) -> Self {
851 Soa { mname, rname, serial, refresh, retry, expire, minimum }
852 }
853
854 pub fn mname(&self) -> &N {
856 &self.mname
857 }
858
859 pub fn rname(&self) -> &N {
861 &self.rname
862 }
863
864 pub fn serial(&self) -> Serial {
866 self.serial
867 }
868
869 pub fn refresh(&self) -> u32 {
871 self.refresh
872 }
873
874 pub fn retry(&self) -> u32 {
876 self.retry
877 }
878
879 pub fn expire(&self) -> u32 {
881 self.expire
882 }
883
884 pub fn minimum(&self) -> u32 {
886 self.minimum
887 }
888}
889
890
891impl<N: Parse> Parse for Soa<N> where N::Err: From<ShortBuf> {
894 type Err = N::Err;
895
896 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
897 Ok(Self::new(N::parse(parser)?, N::parse(parser)?,
898 Serial::parse(parser)?, u32::parse(parser)?,
899 u32::parse(parser)?, u32::parse(parser)?,
900 u32::parse(parser)?))
901 }
902
903 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
904 N::skip(parser)?;
905 N::skip(parser)?;
906 Serial::skip(parser)?;
907 u32::skip(parser)?;
908 u32::skip(parser)?;
909 u32::skip(parser)?;
910 u32::skip(parser)?;
911 Ok(())
912 }
913}
914
915impl<N: ParseAll + Parse> ParseAll for Soa<N>
916 where <N as ParseAll>::Err: From<<N as Parse>::Err>,
917 <N as ParseAll>::Err: From<ParseAllError>,
918 <N as Parse>::Err: From<ShortBuf> {
919 type Err = <N as ParseAll>::Err;
920
921 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
922 let mut tmp = parser.clone();
923 let res = <Self as Parse>::parse(&mut tmp)?;
924 if tmp.pos() - parser.pos() < len {
925 Err(ParseAllError::TrailingData.into())
926 }
927 else if tmp.pos() - parser.pos() > len {
928 Err(ParseAllError::ShortField.into())
929 }
930 else {
931 parser.advance(len)?;
932 Ok(res)
933 }
934 }
935}
936
937impl<N: Compose> Compose for Soa<N> {
938 fn compose_len(&self) -> usize {
939 self.mname.compose_len() + self.rname.compose_len() + (5 * 4)
940 }
941
942 fn compose<B: BufMut>(&self, buf: &mut B) {
943 self.mname.compose(buf);
944 self.rname.compose(buf);
945 self.serial.compose(buf);
946 self.refresh.compose(buf);
947 self.retry.compose(buf);
948 self.expire.compose(buf);
949 self.minimum.compose(buf);
950 }
951}
952
953impl<N: Compress> Compress for Soa<N> {
954 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
955 self.mname.compress(buf)?;
956 self.rname.compress(buf)?;
957 buf.compose(&self.serial)?;
958 buf.compose(&self.refresh)?;
959 buf.compose(&self.retry)?;
960 buf.compose(&self.expire)?;
961 buf.compose(&self.minimum)
962 }
963}
964
965
966impl<N: Scan> Scan for Soa<N> {
969 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
970 -> Result<Self, ScanError> {
971 Ok(Self::new(N::scan(scanner)?, N::scan(scanner)?,
972 Serial::scan(scanner)?, u32::scan(scanner)?,
973 u32::scan(scanner)?, u32::scan(scanner)?,
974 u32::scan(scanner)?))
975 }
976}
977
978impl<N: fmt::Display> fmt::Display for Soa<N> {
979 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
980 write!(f, "{}. {}. {} {} {} {} {}",
981 self.mname, self.rname, self.serial, self.refresh, self.retry,
982 self.expire, self.minimum)
983 }
984}
985
986
987impl<N> RtypeRecordData for Soa<N> {
990 const RTYPE: Rtype = Rtype::Soa;
991}
992
993
994#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1002pub struct Txt {
1003 text: Bytes,
1004}
1005
1006impl Txt {
1007 pub fn new(text: CharStr) -> Self {
1009 Txt { text: text.into_bytes() }
1010 }
1011
1012 pub fn iter(&self) -> TxtIter {
1017 TxtIter::new(self.text.clone())
1018 }
1019
1020 pub fn text(&self) -> Bytes {
1029 if self.text[0] as usize == self.text.len() + 1 {
1030 self.text.slice_from(1)
1031 }
1032 else {
1033 let mut res = BytesMut::with_capacity(self.text.len());
1036 for item in self.iter() {
1037 res.put_slice(item.as_ref());
1038 }
1039 res.freeze()
1040 }
1041 }
1042}
1043
1044
1045impl IntoIterator for Txt {
1048 type Item = CharStr;
1049 type IntoIter = TxtIter;
1050
1051 fn into_iter(self) -> Self::IntoIter {
1052 self.iter()
1053 }
1054}
1055
1056impl<'a> IntoIterator for &'a Txt {
1057 type Item = CharStr;
1058 type IntoIter = TxtIter;
1059
1060 fn into_iter(self) -> Self::IntoIter {
1061 self.iter()
1062 }
1063}
1064
1065
1066impl ParseAll for Txt {
1069 type Err = ParseOpenError;
1070
1071 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
1072 let text = parser.parse_bytes(len)?;
1073 let mut tmp = Parser::from_bytes(text.clone());
1074 while tmp.remaining() > 0 {
1075 CharStr::skip(&mut tmp).map_err(|_| ParseOpenError::ShortField)?
1076 }
1077 Ok(Txt { text })
1078 }
1079}
1080
1081impl Compose for Txt {
1082 fn compose_len(&self) -> usize {
1083 self.text.len()
1084 }
1085
1086 fn compose<B: BufMut>(&self, buf: &mut B) {
1087 buf.put_slice(self.text.as_ref())
1088 }
1089}
1090
1091impl Compress for Txt {
1092 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
1093 buf.compose(self)
1094 }
1095}
1096
1097
1098impl Scan for Txt {
1101 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
1102 -> Result<Self, ScanError> {
1103 let first = CharStr::scan(scanner)?;
1104 let second = match CharStr::scan(scanner) {
1105 Err(_) => return Ok(Txt::new(first)),
1106 Ok(second) => second,
1107 };
1108 let mut text = first.into_bytes();
1109 text.extend_from_slice(second.as_ref());
1110 while let Ok(some) = CharStr::scan(scanner) {
1111 text.extend_from_slice(some.as_ref());
1112 }
1113 Ok(Txt { text })
1114 }
1115}
1116
1117impl fmt::Display for Txt {
1118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1119 let mut items = self.iter();
1120 match items.next() {
1121 Some(item) => item.fmt(f)?,
1122 None => return Ok(())
1123 }
1124 for item in items {
1125 write!(f, " {}", item)?;
1126 }
1127 Ok(())
1128 }
1129}
1130
1131
1132impl RtypeRecordData for Txt {
1135 const RTYPE: Rtype = Rtype::Txt;
1136}
1137
1138
1139#[derive(Clone, Debug)]
1143pub struct TxtIter {
1144 parser: Parser,
1145}
1146
1147impl TxtIter {
1148 fn new(text: Bytes)-> Self {
1149 TxtIter { parser: Parser::from_bytes(text) }
1150 }
1151}
1152
1153impl Iterator for TxtIter {
1154 type Item = CharStr;
1155
1156 fn next(&mut self) -> Option<Self::Item> {
1157 if self.parser.remaining() == 0 {
1158 None
1159 }
1160 else {
1161 Some(CharStr::parse(&mut self.parser).unwrap())
1162 }
1163 }
1164}
1165
1166
1167#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1176pub struct Wks {
1177 address: Ipv4Addr,
1178 protocol: u8,
1179 bitmap: Bytes,
1180}
1181
1182
1183impl Wks {
1184 pub fn new(address: Ipv4Addr, protocol: u8, bitmap: Bytes) -> Self {
1186 Wks { address, protocol, bitmap }
1187 }
1188
1189 pub fn address(&self) -> Ipv4Addr {
1191 self.address
1192 }
1193
1194 pub fn protocol(&self) -> u8 {
1198 self.protocol
1199 }
1200
1201 pub fn bitmap(&self) -> &Bytes {
1203 &self.bitmap
1204 }
1205
1206 pub fn serves(&self, port: u16) -> bool {
1208 let octet = (port / 8) as usize;
1209 let bit = (port % 8) as usize;
1210 match self.bitmap.get(octet) {
1211 Some(x) => (x >> bit) > 0,
1212 None => false
1213 }
1214 }
1215
1216 pub fn iter(&self) -> WksIter {
1218 WksIter::new(self.bitmap.clone())
1219 }
1220}
1221
1222
1223impl ParseAll for Wks {
1226 type Err = ParseOpenError;
1227
1228 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
1229 if len < 5 {
1230 return Err(ParseOpenError::ShortField)
1231 }
1232 Ok(Self::new(Ipv4Addr::parse(parser)?, u8::parse(parser)?,
1233 parser.parse_bytes(len - 5)?))
1234 }
1235}
1236
1237impl Compose for Wks {
1238 fn compose_len(&self) -> usize {
1239 self.bitmap.len() + 5
1240 }
1241
1242 fn compose<B: BufMut>(&self, buf: &mut B) {
1243 self.address.compose(buf);
1244 self.protocol.compose(buf);
1245 self.bitmap.compose(buf);
1246 }
1247}
1248
1249impl Compress for Wks {
1250 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
1251 buf.compose(self)
1252 }
1253}
1254
1255
1256impl Scan for Wks {
1259 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
1260 -> Result<Self, ScanError> {
1261 let address = scanner.scan_string_phrase(|res| {
1262 Ipv4Addr::from_str(&res).map_err(Into::into)
1263 })?;
1264 let protocol = u8::scan(scanner)?;
1265 let mut builder = WksBuilder::new(address, protocol);
1266 while let Ok(service) = u16::scan(scanner) {
1267 builder.add_service(service)
1268 }
1269 Ok(builder.finish())
1270 }
1271}
1272
1273impl fmt::Display for Wks {
1274 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1275 write!(f, "{} {}", self.address, self.protocol)?;
1276 for service in self.iter() {
1277 write!(f, " {}", service)?;
1278 }
1279 Ok(())
1280 }
1281}
1282
1283
1284impl RtypeRecordData for Wks {
1287 const RTYPE: Rtype = Rtype::Wks;
1288}
1289
1290
1291#[derive(Clone, Debug)]
1297pub struct WksIter {
1298 bitmap: Bytes,
1299 octet: usize,
1300 bit: usize
1301}
1302
1303impl WksIter {
1304 fn new(bitmap: Bytes) -> Self {
1305 WksIter { bitmap, octet: 0, bit: 0 }
1306 }
1307
1308 fn serves(&self) -> bool {
1309 (self.bitmap[self.octet] >> self.bit) > 0
1310 }
1311}
1312
1313impl Iterator for WksIter {
1314 type Item = u16;
1315
1316 fn next(&mut self) -> Option<Self::Item> {
1317 loop {
1318 if self.octet >= self.bitmap.len() { return None }
1319 else {
1320 if self.serves() {
1321 return Some((self.octet * 8 + self.bit) as u16)
1322 }
1323 if self.bit == 7 { self.octet += 1; self.bit = 0 }
1324 else { self.bit += 1 }
1325 }
1326 }
1327 }
1328}
1329
1330
1331#[derive(Clone, Debug)]
1334pub struct WksBuilder {
1335 address: Ipv4Addr,
1336 protocol: u8,
1337 bitmap: BytesMut,
1338}
1339
1340impl WksBuilder {
1341 pub fn new(address: Ipv4Addr, protocol: u8) -> Self {
1342 WksBuilder { address, protocol, bitmap: BytesMut::new() }
1343 }
1344
1345 pub fn add_service(&mut self, service: u16) {
1346 let octet = (service >> 2) as usize;
1347 let bit = 1 << (service & 0x3);
1348 while self.bitmap.len() < octet + 1 {
1349 self.bitmap.extend_from_slice(b"0")
1350 }
1351 self.bitmap[octet] |= bit;
1352 }
1353
1354 pub fn finish(self) -> Wks {
1355 Wks::new(self.address, self.protocol, self.bitmap.freeze())
1356 }
1357}
1358
1359
1360pub mod parsed {
1363 use ::bits::name::ParsedDname;
1364
1365 pub use super::A;
1366 pub type Cname = super::Cname<ParsedDname>;
1367 pub use super::Hinfo;
1368 pub type Mb = super::Mb<ParsedDname>;
1369 pub type Md = super::Md<ParsedDname>;
1370 pub type Mf = super::Mf<ParsedDname>;
1371 pub type Mg = super::Mg<ParsedDname>;
1372 pub type Minfo = super::Minfo<ParsedDname>;
1373 pub type Mr = super::Mr<ParsedDname>;
1374 pub type Mx = super::Mx<ParsedDname>;
1375 pub type Ns = super::Ns<ParsedDname>;
1376 pub use super::Null;
1377 pub type Ptr = super::Ptr<ParsedDname>;
1378 pub type Soa = super::Soa<ParsedDname>;
1379 pub use super::Txt;
1380 pub use super::Wks;
1381}
1382