1macro_rules! rdata_types {
7 ( $(
8 $module:ident::{
9 $(
10 zone {
11 $( $mtype:ident $( < $( $mn:ident ),* > ),* $(,)? )*
12 }
13 )*
14 $(
15 pseudo {
16 $( $ptype:ident $( < $( $pn:ident ),* > ),* $(,)? )*
17 }
18 )*
19
20 }
21 )* ) => {
22 $(
23 pub use self::$module::{
24 $( $( $mtype, )* )*
25 $( $( $ptype ),* )*
26 };
27 )*
28
29 $(
30 pub mod $module;
31 )*
32
33 use crate::base::name::{ParsedDname, ToDname};
34 use crate::base::wire::Composer;
35 use crate::base::rdata::ComposeRecordData;
36 use octseq::octets::OctetsFrom;
37
38
39 #[derive(Clone)]
47 #[cfg_attr(
48 feature = "serde",
49 derive(serde::Serialize, serde::Deserialize)
50 )]
51 #[cfg_attr(
52 feature = "serde",
53 serde(bound(
54 serialize = "
55 O: AsRef<[u8]> + octseq::serde::SerializeOctets,
56 N: serde::Serialize,
57 ",
58 deserialize = "
59 O: octseq::builder::FromBuilder
60 + octseq::serde::DeserializeOctets<'de>,
61 <O as octseq::builder::FromBuilder>::Builder:
62 octseq::builder::EmptyBuilder
63 + octseq::builder::Truncate
64 + AsRef<[u8]> + AsMut<[u8]>,
65 N: serde::Deserialize<'de>,
66 ",
67 ))
68 )]
69 #[non_exhaustive]
70 pub enum ZoneRecordData<O, N> {
71 $( $( $(
72 $mtype($mtype $( < $( $mn ),* > )*),
73 )* )* )*
74 Unknown($crate::base::rdata::UnknownRecordData<O>),
75 }
76
77 impl<Octets: AsRef<[u8]>, Name: ToDname> ZoneRecordData<Octets, Name> {
78 pub fn scan<S>(
84 rtype: $crate::base::iana::Rtype,
85 scanner: &mut S
86 ) -> Result<Self, S::Error>
87 where
88 S: $crate::base::scan::Scanner<Octets = Octets, Dname = Name>
89 {
90 use $crate::base::rdata::UnknownRecordData;
91 use $crate::base::scan::ScannerError;
92
93 if scanner.scan_opt_unknown_marker()? {
94 UnknownRecordData::scan_without_marker(
95 rtype, scanner
96 ).map(ZoneRecordData::Unknown)
97 }
98 else {
99 match rtype {
100 $( $( $(
101 $crate::base::iana::Rtype::$mtype => {
102 $mtype::scan(
103 scanner
104 ).map(ZoneRecordData::$mtype)
105 }
106 )* )* )*
107 _ => {
108 Err(S::Error::custom(
109 "unknown record type with concrete data"
110 ))
111 }
112 }
113 }
114 }
115 }
116
117 impl<O, N> ZoneRecordData<O, N> {
118 fn rtype(&self) -> $crate::base::iana::Rtype {
119 use $crate::base::rdata::RecordData;
120
121 match *self {
122 $( $( $(
123 ZoneRecordData::$mtype(ref inner) => {
124 inner.rtype()
125 }
130 )* )* )*
131 ZoneRecordData::Unknown(ref inner) => inner.rtype(),
132 }
133 }
134 }
135
136 impl<Octets, SrcOctets, Name, SrcName>
139 octseq::octets::OctetsFrom<
140 ZoneRecordData<SrcOctets, SrcName>
141 >
142 for ZoneRecordData<Octets, Name>
143 where
144 Octets: octseq::octets::OctetsFrom<SrcOctets>,
145 Name: octseq::octets::OctetsFrom<
146 SrcName, Error = Octets::Error
147 >,
148 {
149 type Error = Octets::Error;
150
151 fn try_octets_from(
152 source: ZoneRecordData<SrcOctets, SrcName>
153 ) -> Result<Self, Self::Error> {
154 match source {
155 $( $( $(
156 ZoneRecordData::$mtype(inner) => {
157 inner.convert_octets().map(
158 ZoneRecordData::$mtype
159 )
160 }
161 )* )* )*
162 ZoneRecordData::Unknown(inner) => {
163 Ok(ZoneRecordData::Unknown(
164 $crate::base::rdata::
165 UnknownRecordData::try_octets_from(inner)?
166 ))
167 }
168 }
169 }
170 }
171
172 impl<Octets, TargetOctets, Name, TargetName>
175 crate::base::name::FlattenInto<
176 ZoneRecordData<TargetOctets, TargetName>
177 >
178 for ZoneRecordData<Octets, Name>
179 where
180 TargetOctets: OctetsFrom<Octets>,
181 Name: crate::base::name::FlattenInto<
182 TargetName,
183 AppendError = TargetOctets::Error,
184 >,
185 {
186 type AppendError = TargetOctets::Error;
187
188 fn try_flatten_into(
189 self
190 ) -> Result<
191 ZoneRecordData<TargetOctets, TargetName>,
192 Self::AppendError
193 > {
194 match self {
195 $( $( $(
196 ZoneRecordData::$mtype(inner) => {
197 inner.flatten().map(
198 ZoneRecordData::$mtype
199 )
200 }
201 )* )* )*
202 ZoneRecordData::Unknown(inner) => {
203 Ok(ZoneRecordData::Unknown(
204 $crate::base::rdata::
205 UnknownRecordData::try_octets_from(inner)?
206 ))
207 }
208 }
209 }
210 }
211
212 $( $( $(
215 impl<O, N> From<$mtype $( < $( $mn ),* >)*>
216 for ZoneRecordData<O, N> {
217 fn from(value: $mtype $( < $( $mn ),* >)*) -> Self {
218 ZoneRecordData::$mtype(value)
219 }
220 }
221 )* )* )*
222
223 impl<O, N> From<$crate::base::rdata::UnknownRecordData<O>>
224 for ZoneRecordData<O, N> {
225 fn from(value: $crate::base::rdata::UnknownRecordData<O>) -> Self {
226 ZoneRecordData::Unknown(value)
227 }
228 }
229
230
231 impl<O, OO, N, NN> PartialEq<ZoneRecordData<OO, NN>>
234 for ZoneRecordData<O, N>
235 where
236 O: AsRef<[u8]>, OO: AsRef<[u8]>,
237 N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname,
238 {
239 fn eq(&self, other: &ZoneRecordData<OO, NN>) -> bool {
240 match (self, other) {
241 $( $( $(
242 (
243 &ZoneRecordData::$mtype(ref self_inner),
244 &ZoneRecordData::$mtype(ref other_inner)
245 )
246 => {
247 self_inner.eq(other_inner)
248 }
249 )* )* )*
250 (
251 &ZoneRecordData::Unknown(ref self_inner),
252 &ZoneRecordData::Unknown(ref other_inner)
253 ) => {
254 self_inner.eq(other_inner)
255 }
256 _ => false
257 }
258 }
259 }
260
261 impl<O, N> Eq for ZoneRecordData<O, N>
262 where O: AsRef<[u8]>, N: $crate::base::name::ToDname { }
263
264
265 impl<O, OO, N, NN> PartialOrd<ZoneRecordData<OO, NN>>
268 for ZoneRecordData<O, N>
269 where
270 O: AsRef<[u8]>, OO: AsRef<[u8]>,
271 N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname,
272 {
273 fn partial_cmp(
274 &self,
275 other: &ZoneRecordData<OO, NN>
276 ) -> Option<core::cmp::Ordering> {
277 match (self, other) {
278 $( $( $(
279 (
280 &ZoneRecordData::$mtype(ref self_inner),
281 &ZoneRecordData::$mtype(ref other_inner)
282 )
283 => {
284 self_inner.partial_cmp(other_inner)
285 }
286 )* )* )*
287 (
288 &ZoneRecordData::Unknown(ref self_inner),
289 &ZoneRecordData::Unknown(ref other_inner)
290 ) => {
291 self_inner.partial_cmp(other_inner)
292 }
293 _ => self.rtype().partial_cmp(&other.rtype())
294 }
295 }
296 }
297
298 impl<O, OO, N, NN>
299 $crate::base::cmp::CanonicalOrd<ZoneRecordData<OO, NN>>
300 for ZoneRecordData<O, N>
301 where
302 O: AsRef<[u8]>, OO: AsRef<[u8]>,
303 N: $crate::base::cmp::CanonicalOrd<NN>
304 + $crate::base::name::ToDname,
305 NN: $crate::base::name::ToDname,
306 {
307 fn canonical_cmp(
308 &self,
309 other: &ZoneRecordData<OO, NN>
310 ) -> core::cmp::Ordering {
311 match (self, other) {
312 $( $( $(
313 (
314 &ZoneRecordData::$mtype(ref self_inner),
315 &ZoneRecordData::$mtype(ref other_inner)
316 )
317 => {
318 self_inner.canonical_cmp(other_inner)
319 }
320 )* )* )*
321 (
322 &ZoneRecordData::Unknown(ref self_inner),
323 &ZoneRecordData::Unknown(ref other_inner)
324 ) => {
325 self_inner.canonical_cmp(other_inner)
326 }
327 _ => self.rtype().cmp(&other.rtype())
328 }
329 }
330 }
331
332 impl<O, N> core::hash::Hash for ZoneRecordData<O, N>
335 where O: AsRef<[u8]>, N: core::hash::Hash {
336 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
337 match *self {
338 $( $( $(
339 ZoneRecordData::$mtype(ref inner) => {
340 $crate::base::iana::Rtype::$mtype.hash(state);
341 inner.hash(state)
342 }
343 )* )* )*
344 ZoneRecordData::Unknown(ref inner) => {
345 inner.rtype().hash(state);
346 inner.data().as_ref().hash(state);
347 }
348 }
349 }
350 }
351
352 impl<O, N> $crate::base::rdata::RecordData for ZoneRecordData<O, N> {
355 fn rtype(&self) -> $crate::base::iana::Rtype {
356 ZoneRecordData::rtype(self)
357 }
358 }
359
360 impl<'a, Octs: octseq::octets::Octets + ?Sized>
361 $crate::base::rdata::ParseRecordData<'a, Octs>
362 for ZoneRecordData<Octs::Range<'a>, ParsedDname<Octs::Range<'a>>> {
363 fn parse_rdata(
364 rtype: $crate::base::iana::Rtype,
365 parser: &mut octseq::parse::Parser<'a, Octs>,
366 ) -> Result<Option<Self>, $crate::base::wire::ParseError> {
367 match rtype {
368 $( $( $(
369 $crate::base::iana::Rtype::$mtype => {
370 Ok(Some(ZoneRecordData::$mtype(
371 $mtype::parse(parser)?
372 )))
373 }
374 )* )* )*
375 _ => {
376 Ok($crate::base::rdata::UnknownRecordData::parse_rdata(
377 rtype, parser
378 )?.map(ZoneRecordData::Unknown))
379 }
380 }
381 }
382 }
383
384 impl<Octs, Name> ComposeRecordData for ZoneRecordData<Octs, Name>
385 where Octs: AsRef<[u8]>, Name: ToDname {
386 fn rdlen(&self, compress: bool) -> Option<u16> {
387 match *self {
388 $( $( $(
389 ZoneRecordData::$mtype(ref inner) => {
390 inner.rdlen(compress)
391 }
392 )* )* )*
393 ZoneRecordData::Unknown(ref inner) => {
394 inner.rdlen(compress)
395 }
396 }
397 }
398
399 fn compose_rdata<Target: Composer + ?Sized>(
400 &self, target: &mut Target
401 ) -> Result<(), Target::AppendError> {
402 match *self {
403 $( $( $(
404 ZoneRecordData::$mtype(ref inner) => {
405 inner.compose_rdata(target)
406 }
407 )* )* )*
408 ZoneRecordData::Unknown(ref inner) => {
409 inner.compose_rdata(target)
410 }
411 }
412 }
413
414 fn compose_canonical_rdata<Target: Composer + ?Sized>(
415 &self, target: &mut Target
416 ) -> Result<(), Target::AppendError> {
417 match *self {
418 $( $( $(
419 ZoneRecordData::$mtype(ref inner) => {
420 inner.compose_canonical_rdata(target)
421 }
422 )* )* )*
423 ZoneRecordData::Unknown(ref inner) => {
424 inner.compose_canonical_rdata(target)
425 }
426 }
427 }
428 }
429
430
431 impl<O, N> core::fmt::Display for ZoneRecordData<O, N>
434 where
435 O: AsRef<[u8]>,
436 N: core::fmt::Display
437 {
438 fn fmt(&self, f: &mut core::fmt::Formatter)
439 -> core::fmt::Result {
440 match *self {
441 $( $( $(
442 ZoneRecordData::$mtype(ref inner) => {
443 inner.fmt(f)
444 }
445 )* )* )*
446 ZoneRecordData::Unknown(ref inner) => inner.fmt(f),
447 }
448 }
449 }
450
451 impl<O, N> core::fmt::Debug for ZoneRecordData<O, N>
454 where
455 O: AsRef<[u8]>,
456 N: core ::fmt::Debug
457 {
458 fn fmt(&self, f: &mut core::fmt::Formatter)
459 -> core::fmt::Result {
460 match *self {
461 $( $( $(
462 ZoneRecordData::$mtype(ref inner) => {
463 f.write_str(
464 concat!(
465 "ZoneRecordData::",
466 stringify!($mtype),
467 "("
468 )
469 )?;
470 core::fmt::Debug::fmt(inner, f)?;
471 f.write_str(")")
472 }
473 )* )* )*
474 ZoneRecordData::Unknown(ref inner) => {
475 f.write_str("ZoneRecordData::Unknown(")?;
476 core::fmt::Debug::fmt(inner, f)?;
477 f.write_str(")")
478 }
479 }
480 }
481 }
482
483 #[derive(Clone)]
490 #[non_exhaustive]
491 pub enum AllRecordData<O, N> {
492 $( $( $(
493 $mtype($mtype $( < $( $mn ),* > )*),
494 )* )* )*
495 $( $( $(
496 $ptype($ptype $( < $( $pn ),* > )*),
497 )* )* )*
498 Opt($crate::base::opt::Opt<O>),
499 Unknown($crate::base::rdata::UnknownRecordData<O>),
500 }
501
502 impl<O, N> AllRecordData<O, N> {
503 fn rtype(&self) -> $crate::base::iana::Rtype {
504 use $crate::base::rdata::RecordData;
505
506 match *self {
507 $( $( $(
508 AllRecordData::$mtype(ref inner) => {
509 inner.rtype()
510 }
511 )* )* )*
512 $( $( $(
513 AllRecordData::$ptype(ref inner) => {
514 inner.rtype()
515 }
516 )* )* )*
517
518 AllRecordData::Opt(_) => $crate::base::iana::Rtype::Opt,
519 AllRecordData::Unknown(ref inner) => inner.rtype(),
520 }
521 }
522 }
523
524 $( $( $(
527 impl<O, N> From<$mtype $( < $( $mn ),* > )*>
528 for AllRecordData<O, N> {
529 fn from(value: $mtype $( < $( $mn ),* >)*) -> Self {
530 AllRecordData::$mtype(value)
531 }
532 }
533 )* )* )*
534
535 $( $( $(
536 impl<O, N> From<$ptype $( < $( $pn ),* > )*>
537 for AllRecordData<O, N> {
538 fn from(value: $ptype $( < $( $pn ),* >)*) -> Self {
539 AllRecordData::$ptype(value)
540 }
541 }
542 )* )* )*
543
544 impl<O, N> From<$crate::base::opt::Opt<O>> for AllRecordData<O, N> {
545 fn from(value: $crate::base::opt::Opt<O>) -> Self {
546 AllRecordData::Opt(value)
547 }
548 }
549
550 impl<O, N> From<$crate::base::rdata::UnknownRecordData<O>>
551 for AllRecordData<O, N> {
552 fn from(
553 value: $crate::base::rdata::UnknownRecordData<O>
554 ) -> Self {
555 AllRecordData::Unknown(value)
556 }
557 }
558
559 impl<O, N> From<AllRecordData<O, N>>
560 for Result<ZoneRecordData<O, N>, AllRecordData<O, N>> {
561 fn from(
562 value: AllRecordData<O, N>
563 ) -> Result<ZoneRecordData<O, N>, AllRecordData<O, N>> {
564 match value {
565 $( $( $(
566 AllRecordData::$mtype(inner) => {
567 Ok(ZoneRecordData::$mtype(inner))
568 }
569 )* )* )*
570 AllRecordData::Unknown(inner) => {
571 Ok(ZoneRecordData::Unknown(inner))
572 }
573 value => Err(value),
574 }
575 }
576 }
577
578 impl<Octets, SrcOctets, Name, SrcName>
581 octseq::octets::OctetsFrom<
582 AllRecordData<SrcOctets, SrcName>
583 >
584 for AllRecordData<Octets, Name>
585 where
586 Octets: octseq::octets::OctetsFrom<SrcOctets>,
587 Name: octseq::octets::OctetsFrom<
588 SrcName, Error = Octets::Error,
589 >,
590 {
591 type Error = Octets::Error;
592
593 fn try_octets_from(
594 source: AllRecordData<SrcOctets, SrcName>
595 ) -> Result<Self, Self::Error> {
596 match source {
597 $( $( $(
598 AllRecordData::$mtype(inner) => {
599 inner.convert_octets().map(
600 AllRecordData::$mtype
601 )
602 }
603 )* )* )*
604 $( $( $(
605 AllRecordData::$ptype(inner) => {
606 inner.convert_octets().map(
607 AllRecordData::$ptype
608 )
609 }
610 )* )* )*
611 AllRecordData::Opt(inner) => {
612 Ok(AllRecordData::Opt(
613 $crate::base::opt::Opt::try_octets_from(inner)?
614 ))
615 }
616 AllRecordData::Unknown(inner) => {
617 Ok(AllRecordData::Unknown(
618 $crate::base::rdata::UnknownRecordData
619 ::try_octets_from(inner)?
620 ))
621 }
622 }
623 }
624 }
625
626 impl<Octets, TargetOctets, Name, TargetName>
629 crate::base::name::FlattenInto<
630 AllRecordData<TargetOctets, TargetName>
631 >
632 for AllRecordData<Octets, Name>
633 where
634 TargetOctets: OctetsFrom<Octets>,
635 Name: crate::base::name::FlattenInto<
636 TargetName,
637 AppendError = TargetOctets::Error,
638 >,
639 {
640 type AppendError = TargetOctets::Error;
641
642 fn try_flatten_into(
643 self
644 ) -> Result<
645 AllRecordData<TargetOctets, TargetName>,
646 Self::AppendError
647 > {
648 match self {
649 $( $( $(
650 AllRecordData::$mtype(inner) => {
651 inner.flatten().map(
652 AllRecordData::$mtype
653 )
654 }
655 )* )* )*
656 $( $( $(
657 AllRecordData::$ptype(inner) => {
658 inner.flatten().map(
659 AllRecordData::$ptype
660 )
661 }
662 )* )* )*
663 AllRecordData::Opt(inner) => {
664 Ok(AllRecordData::Opt(
665 $crate::base::opt::Opt::try_octets_from(inner)?
666 ))
667 }
668 AllRecordData::Unknown(inner) => {
669 Ok(AllRecordData::Unknown(
670 $crate::base::rdata::
671 UnknownRecordData::try_octets_from(inner)?
672 ))
673 }
674 }
675 }
676 }
677
678
679 impl<O, OO, N, NN> PartialEq<AllRecordData<OO, NN>>
682 for AllRecordData<O, N>
683 where
684 O: AsRef<[u8]>, OO: AsRef<[u8]>,
685 N: $crate::base::name::ToDname, NN: $crate::base::name::ToDname
686 {
687 fn eq(&self, other: &AllRecordData<OO, NN>) -> bool {
688 match (self, other) {
689 $( $( $(
690 (
691 &AllRecordData::$mtype(ref left),
692 &AllRecordData::$mtype(ref right)
693 ) => {
694 left.eq(right)
695 }
696 )* )* )*
697 $( $( $(
698 (
699 &AllRecordData::$ptype(ref left),
700 &AllRecordData::$ptype(ref right)
701 ) => {
702 left.eq(right)
703 }
704 )* )* )*
705 (_, _) => false
706 }
707 }
708 }
709
710 impl<O, N> Eq for AllRecordData<O, N>
711 where O: AsRef<[u8]>, N: $crate::base::name::ToDname { }
712
713
714 impl<O, N> core::hash::Hash for AllRecordData<O, N>
717 where O: AsRef<[u8]>, N: core::hash::Hash {
718 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
719 self.rtype().hash(state);
720 match *self {
721 $( $( $(
722 AllRecordData::$mtype(ref inner) => {
723 inner.hash(state)
724 }
725 )* )* )*
726 $( $( $(
727 AllRecordData::$ptype(ref inner) => {
728 inner.hash(state)
729 }
730 )* )* )*
731 AllRecordData::Opt(ref inner) => {
732 inner.hash(state);
733 }
734 AllRecordData::Unknown(ref inner) => {
735 inner.data().as_ref().hash(state);
736 }
737 }
738 }
739 }
740
741 impl<O, N> $crate::base::rdata::RecordData for AllRecordData<O, N> {
744 fn rtype(&self) -> $crate::base::iana::Rtype {
745 match *self {
746 $( $( $(
747 AllRecordData::$mtype(ref inner) => {
748 inner.rtype()
749 }
750 )* )* )*
751 $( $( $(
752 AllRecordData::$ptype(ref inner) => {
753 inner.rtype()
754 }
755 )* )* )*
756 AllRecordData::Opt(ref inner) => inner.rtype(),
757 AllRecordData::Unknown(ref inner) => inner.rtype(),
758 }
759 }
760 }
761
762 impl<'a, Octs: octseq::octets::Octets>
763 $crate::base::rdata::ParseRecordData<'a, Octs>
764 for AllRecordData<Octs::Range<'a>, ParsedDname<Octs::Range<'a>>> {
765 fn parse_rdata(
766 rtype: $crate::base::iana::Rtype,
767 parser: &mut octseq::parse::Parser<'a, Octs>,
768 ) -> Result<Option<Self>, crate::base::wire::ParseError> {
769 match rtype {
770 $( $( $(
771 $crate::base::iana::Rtype::$mtype => {
772 Ok(Some(AllRecordData::$mtype(
773 $mtype::parse(parser)?
774 )))
775 }
776 )* )* )*
777 $( $( $(
778 $crate::base::iana::Rtype::$ptype => {
779 Ok(Some(AllRecordData::$ptype(
780 $ptype::parse(parser)?
781 )))
782 }
783 )* )* )*
784 $crate::base::iana::Rtype::Opt => {
785 Ok(Some(AllRecordData::Opt(
786 $crate::base::opt::Opt::parse(parser)?
787 )))
788 }
789 _ => {
790 Ok($crate::base::rdata::UnknownRecordData::parse_rdata(
791 rtype, parser
792 )?.map(AllRecordData::Unknown))
793 }
794 }
795 }
796 }
797
798 impl<Octs, Name> ComposeRecordData for AllRecordData<Octs, Name>
799 where Octs: AsRef<[u8]>, Name: ToDname {
800 fn rdlen(&self, compress: bool) -> Option<u16> {
801 match *self {
802 $( $( $(
803 AllRecordData::$mtype(ref inner) => {
804 inner.rdlen(compress)
805 }
806 )* )* )*
807 $( $( $(
808 AllRecordData::$ptype(ref inner) => {
809 inner.rdlen(compress)
810 }
811 )* )* )*
812 AllRecordData::Opt(ref inner) => {
813 inner.rdlen(compress)
814 }
815 AllRecordData::Unknown(ref inner) => {
816 inner.rdlen(compress)
817 }
818 }
819 }
820
821 fn compose_rdata<Target: Composer + ?Sized>(
822 &self, target: &mut Target
823 ) -> Result<(), Target::AppendError> {
824 match *self {
825 $( $( $(
826 AllRecordData::$mtype(ref inner) => {
827 inner.compose_rdata(target)
828 }
829 )* )* )*
830 $( $( $(
831 AllRecordData::$ptype(ref inner) => {
832 inner.compose_rdata(target)
833 }
834 )* )* )*
835 AllRecordData::Opt(ref inner) => {
836 inner.compose_rdata(target)
837 }
838 AllRecordData::Unknown(ref inner) => {
839 inner.compose_rdata(target)
840 }
841 }
842 }
843
844 fn compose_canonical_rdata<Target: Composer + ?Sized>(
845 &self, target: &mut Target
846 ) -> Result<(), Target::AppendError> {
847 match *self {
848 $( $( $(
849 AllRecordData::$mtype(ref inner) => {
850 inner.compose_canonical_rdata(target)
851 }
852 )* )* )*
853 $( $( $(
854 AllRecordData::$ptype(ref inner) => {
855 inner.compose_canonical_rdata(target)
856 }
857 )* )* )*
858 AllRecordData::Opt(ref inner) => {
859 inner.compose_canonical_rdata(target)
860 }
861 AllRecordData::Unknown(ref inner) => {
862 inner.compose_canonical_rdata(target)
863 }
864 }
865 }
866 }
867
868
869 impl<O, N> core::fmt::Display for AllRecordData<O, N>
872 where O: octseq::octets::Octets, N: core::fmt::Display {
873 fn fmt(
874 &self, f: &mut core::fmt::Formatter
875 ) -> core::fmt::Result {
876 match *self {
877 $( $( $(
878 AllRecordData::$mtype(ref inner) => {
879 inner.fmt(f)
880 }
881 )* )* )*
882 $( $( $(
883 AllRecordData::$ptype(ref inner) => {
884 inner.fmt(f)
885 }
886 )* )* )*
887 AllRecordData::Opt(ref inner) => inner.fmt(f),
888 AllRecordData::Unknown(ref inner) => inner.fmt(f),
889 }
890 }
891 }
892
893 impl<O, N> core::fmt::Debug for AllRecordData<O, N>
894 where O: octseq::octets::Octets, N: core::fmt::Debug {
895 fn fmt(
896 &self, f: &mut core::fmt::Formatter
897 ) -> core::fmt::Result {
898 match *self {
899 $( $( $(
900 AllRecordData::$mtype(ref inner) => {
901 f.write_str(
902 concat!(
903 "AllRecordData::",
904 stringify!($mtype),
905 "("
906 )
907 )?;
908 core::fmt::Debug::fmt(inner, f)?;
909 f.write_str(")")
910 }
911 )* )* )*
912 $( $( $(
913 AllRecordData::$ptype(ref inner) => {
914 f.write_str(
915 concat!(
916 "AllRecordData::",
917 stringify!($ptype),
918 "("
919 )
920 )?;
921 core::fmt::Debug::fmt(inner, f)?;
922 f.write_str(")")
923 }
924 )* )* )*
925 AllRecordData::Opt(ref inner) => {
926 f.write_str("AllRecordData::Opt(")?;
927 core::fmt::Debug::fmt(inner, f)?;
928 f.write_str(")")
929 }
930 AllRecordData::Unknown(ref inner) => {
931 f.write_str("AllRecordData::Unknown(")?;
932 core::fmt::Debug::fmt(inner, f)?;
933 f.write_str(")")
934 }
935 }
936 }
937 }
938
939 }
940}
941
942macro_rules! dname_type_base {
949 ($(#[$attr:meta])* (
950 $target:ident, $rtype:ident, $field:ident, $into_field:ident
951 ) ) => {
952 $(#[$attr])*
953 #[derive(Clone, Debug)]
954 #[cfg_attr(
955 feature = "serde",
956 derive(serde::Serialize, serde::Deserialize)
957 )]
958 pub struct $target<N: ?Sized> {
959 $field: N
960 }
961
962 impl<N> $target<N> {
963 pub fn new($field: N) -> Self {
964 $target { $field }
965 }
966
967 pub fn $field(&self) -> &N {
968 &self.$field
969 }
970
971 pub fn $into_field(self) -> N {
972 self.$field
973 }
974
975 pub fn scan<S: crate::base::scan::Scanner<Dname = N>>(
976 scanner: &mut S
977 ) -> Result<Self, S::Error> {
978 scanner.scan_dname().map(Self::new)
979 }
980
981 pub(super) fn convert_octets<Target: OctetsFrom<N>>(
982 self
983 ) -> Result<$target<Target>, Target::Error> {
984 Target::try_octets_from(self.$field).map($target::new)
985 }
986
987 #[allow(dead_code)] pub(super) fn flatten<Target>(
989 self
990 ) -> Result<$target<Target>, N::AppendError>
991 where
992 N: crate::base::name::FlattenInto<Target>
993 {
994 self.$field.try_flatten_into().map($target::new)
995 }
996 }
997
998 impl<Octs: Octets> $target<ParsedDname<Octs>> {
999 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
1000 parser: &mut Parser<'a, Src>,
1001 ) -> Result<Self, ParseError> {
1002 ParsedDname::parse(parser).map(Self::new)
1003 }
1004 }
1005
1006 impl<N> From<N> for $target<N> {
1009 fn from(name: N) -> Self {
1010 Self::new(name)
1011 }
1012 }
1013
1014 impl<N: FromStr> FromStr for $target<N> {
1015 type Err = N::Err;
1016
1017 fn from_str(s: &str) -> Result<Self, Self::Err> {
1018 N::from_str(s).map(Self::new)
1019 }
1020 }
1021
1022
1023 impl<Name, SrcName> OctetsFrom<$target<SrcName>> for $target<Name>
1026 where Name: OctetsFrom<SrcName> {
1027 type Error = Name::Error;
1028
1029 fn try_octets_from(
1030 source: $target<SrcName>
1031 ) -> Result<Self, Self::Error> {
1032 Name::try_octets_from(source.$field).map(|name| {
1033 Self::new(name)
1034 })
1035 }
1036 }
1037
1038 impl<Name, Target> crate::base::name::FlattenInto<$target<Target>>
1041 for $target<Name>
1042 where Name: crate::base::name::FlattenInto<Target> {
1043 type AppendError = Name::AppendError;
1044
1045 fn try_flatten_into(
1046 self
1047 ) -> Result<$target<Target>, Self::AppendError> {
1048 self.$field.try_flatten_into().map($target::new)
1049 }
1050 }
1051
1052 impl<N, NN> PartialEq<$target<NN>> for $target<N>
1055 where N: ToDname, NN: ToDname {
1056 fn eq(&self, other: &$target<NN>) -> bool {
1057 self.$field.name_eq(&other.$field)
1058 }
1059 }
1060
1061 impl<N: ToDname> Eq for $target<N> { }
1062
1063
1064 impl<N, NN> PartialOrd<$target<NN>> for $target<N>
1069 where N: ToDname, NN: ToDname {
1070 fn partial_cmp(&self, other: &$target<NN>) -> Option<Ordering> {
1071 Some(self.$field.name_cmp(&other.$field))
1072 }
1073 }
1074
1075 impl<N: ToDname> Ord for $target<N> {
1076 fn cmp(&self, other: &Self) -> Ordering {
1077 self.$field.name_cmp(&other.$field)
1078 }
1079 }
1080
1081 impl<N: hash::Hash> hash::Hash for $target<N> {
1084 fn hash<H: hash::Hasher>(&self, state: &mut H) {
1085 self.$field.hash(state)
1086 }
1087 }
1088
1089 impl<N> $crate::base::rdata::RecordData for $target<N> {
1092 fn rtype(&self) -> $crate::base::iana::Rtype {
1093 $crate::base::iana::Rtype::$rtype
1094 }
1095 }
1096
1097 impl<'a, Octs> $crate::base::rdata::ParseRecordData<'a, Octs>
1098 for $target<$crate::base::name::ParsedDname<Octs::Range<'a>>>
1099 where Octs: octseq::octets::Octets + ?Sized {
1100 fn parse_rdata(
1101 rtype: $crate::base::iana::Rtype,
1102 parser: &mut octseq::parse::Parser<'a, Octs>,
1103 ) -> Result<Option<Self>, $crate::base::wire::ParseError> {
1104 if rtype == $crate::base::iana::Rtype::$rtype {
1105 Self::parse(parser).map(Some)
1106 }
1107 else {
1108 Ok(None)
1109 }
1110 }
1111 }
1112
1113 impl<N: fmt::Display> fmt::Display for $target<N> {
1116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1117 write!(f, "{}.", self.$field)
1118 }
1119 }
1120 }
1121}
1122
1123macro_rules! dname_type_well_known {
1124 ($(#[$attr:meta])* (
1125 $target:ident, $rtype:ident, $field:ident, $into_field:ident
1126 ) ) => {
1127 dname_type_base! {
1128 $( #[$attr] )*
1129 ($target, $rtype, $field, $into_field)
1130 }
1131
1132 impl<N: ToDname> $crate::base::rdata::ComposeRecordData
1133 for $target<N> {
1134 fn rdlen(&self, compress: bool) -> Option<u16> {
1135 if compress {
1136 None
1137 }
1138 else {
1139 Some(self.$field.compose_len())
1140 }
1141 }
1142
1143 fn compose_rdata<Target: $crate::base::wire::Composer + ?Sized>(
1144 &self, target: &mut Target
1145 ) -> Result<(), Target::AppendError> {
1146 if target.can_compress() {
1147 target.append_compressed_dname(&self.$field)
1148 }
1149 else {
1150 self.$field.compose(target)
1151 }
1152 }
1153
1154 fn compose_canonical_rdata<Target>(
1155 &self, target: &mut Target
1156 ) -> Result<(), Target::AppendError>
1157 where Target: $crate::base::wire::Composer + ?Sized {
1158 self.$field.compose_canonical(target)
1159 }
1160 }
1161
1162 impl<N: ToDname, NN: ToDname> CanonicalOrd<$target<NN>> for $target<N> {
1163 fn canonical_cmp(&self, other: &$target<NN>) -> Ordering {
1164 self.$field.lowercase_composed_cmp(&other.$field)
1165 }
1166 }
1167 }
1168}
1169
1170macro_rules! dname_type_canonical {
1171 ($(#[$attr:meta])* (
1172 $target:ident, $rtype:ident, $field:ident, $into_field:ident
1173 ) ) => {
1174 dname_type_base! {
1175 $( #[$attr] )*
1176 ($target, $rtype, $field, $into_field)
1177 }
1178
1179 impl<N: ToDname> $crate::base::rdata::ComposeRecordData
1180 for $target<N> {
1181 fn rdlen(&self, _compress: bool) -> Option<u16> {
1182 Some(self.$field.compose_len())
1183 }
1184
1185 fn compose_rdata<Target: $crate::base::wire::Composer + ?Sized>(
1186 &self, target: &mut Target
1187 ) -> Result<(), Target::AppendError> {
1188 self.$field.compose(target)
1189 }
1190
1191 fn compose_canonical_rdata<Target>(
1192 &self, target: &mut Target
1193 ) -> Result<(), Target::AppendError>
1194 where Target: $crate::base::wire::Composer + ?Sized {
1195 self.$field.compose_canonical(target)
1196 }
1197 }
1198
1199 impl<N: ToDname, NN: ToDname> CanonicalOrd<$target<NN>> for $target<N> {
1200 fn canonical_cmp(&self, other: &$target<NN>) -> Ordering {
1201 self.$field.lowercase_composed_cmp(&other.$field)
1202 }
1203 }
1204 }
1205}
1206
1207#[allow(unused_macros)]
1208macro_rules! dname_type {
1209 ($(#[$attr:meta])* (
1210 $target:ident, $rtype:ident, $field:ident, $into_field:ident
1211 ) ) => {
1212 dname_type_base! {
1213 $( #[$attr] )*
1214 ($target, $rtype, $field, $into_field)
1215 }
1216
1217 impl<N: ToDname> $crate::base::rdata::ComposeRecordData
1218 for $target<N> {
1219 fn rdlen(&self, _compress: bool) -> Option<u16> {
1220 Some(self.compose_len)
1221 }
1222
1223 fn compose_rdata<Target: $crate::base::wire::Composer + ?Sized>(
1224 &self, target: &mut Target
1225 ) -> Result<(), Target::AppendError> {
1226 self.$field.compose(target)
1227 }
1228
1229 fn compose_canonical_rdata<Target>(
1230 &self, target: &mut Target
1231 ) -> Result<(), Target::AppendError>
1232 where Target: $crate::base::wire::Composer + ?Sized {
1233 self.$field.compose(target)
1234 }
1235 }
1236
1237 impl<N: ToDname, NN: ToDname> CanonicalOrd<$target<NN>> for $target<N> {
1238 fn canonical_cmp(&self, other: &$target<NN>) -> Ordering {
1239 self.$field.name_cmp(&other.$field)
1240 }
1241 }
1242 }
1243}