1use super::super::cmp::CanonicalOrd;
6use super::super::net::IpAddr;
7use super::super::scan::{Scanner, Symbol, SymbolCharsError, Symbols};
8use super::super::wire::{FormError, ParseError};
9use super::builder::{FromStrError, NameBuilder, PushError};
10use super::label::{Label, LabelTypeError, SplitLabelError};
11use super::relative::{NameIter, RelativeName};
12use super::traits::{FlattenInto, ToLabelIter, ToName};
13#[cfg(feature = "bytes")]
14use bytes::Bytes;
15use core::ops::{Bound, RangeBounds};
16use core::str::FromStr;
17use core::{borrow, cmp, fmt, hash, mem, str};
18use octseq::builder::{
19 EmptyBuilder, FreezeBuilder, FromBuilder, OctetsBuilder, Truncate,
20};
21use octseq::octets::{Octets, OctetsFrom};
22use octseq::parse::Parser;
23#[cfg(feature = "serde")]
24use octseq::serde::{DeserializeOctets, SerializeOctets};
25#[cfg(feature = "std")]
26use std::vec::Vec;
27
28#[derive(Clone)]
52#[repr(transparent)]
53#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
54pub struct Name<Octs: ?Sized>(Octs);
55
56impl Name<()> {
57 pub const MAX_LEN: usize = 255;
59}
60
61impl<Octs> Name<Octs> {
64 pub const unsafe fn from_octets_unchecked(octets: Octs) -> Self {
75 Self(octets)
76 }
77
78 pub fn from_octets(octets: Octs) -> Result<Self, NameError>
84 where
85 Octs: AsRef<[u8]>,
86 {
87 Name::check_slice(octets.as_ref())?;
88 Ok(unsafe { Self::from_octets_unchecked(octets) })
89 }
90
91 pub fn from_symbols<Sym>(symbols: Sym) -> Result<Self, FromStrError>
92 where
93 Octs: FromBuilder,
94 <Octs as FromBuilder>::Builder: EmptyBuilder
95 + FreezeBuilder<Octets = Octs>
96 + AsRef<[u8]>
97 + AsMut<[u8]>,
98 Sym: IntoIterator<Item = Symbol>,
99 {
100 let mut symbols = symbols.into_iter();
103 let first = match symbols.next() {
104 Some(first) => first,
105 None => return Err(SymbolCharsError::short_input().into()),
106 };
107 if first == Symbol::Char('.') {
108 if symbols.next().is_some() {
109 return Err(FromStrError::empty_label());
110 } else {
111 let mut builder =
113 <Octs as FromBuilder>::Builder::with_capacity(1);
114 builder
115 .append_slice(b"\0")
116 .map_err(|_| FromStrError::ShortBuf)?;
117 return Ok(unsafe {
118 Self::from_octets_unchecked(builder.freeze())
119 });
120 }
121 }
122
123 let mut builder = NameBuilder::<Octs::Builder>::new();
124 builder.push_symbol(first)?;
125 builder.append_symbols(symbols)?;
126 builder.into_name().map_err(Into::into)
127 }
128
129 pub fn from_chars<C>(chars: C) -> Result<Self, FromStrError>
148 where
149 Octs: FromBuilder,
150 <Octs as FromBuilder>::Builder: EmptyBuilder
151 + FreezeBuilder<Octets = Octs>
152 + AsRef<[u8]>
153 + AsMut<[u8]>,
154 C: IntoIterator<Item = char>,
155 {
156 Symbols::with(chars.into_iter(), |symbols| {
157 Self::from_symbols(symbols)
158 })
159 }
160
161 pub fn scan<S: Scanner<Name = Self>>(
163 scanner: &mut S,
164 ) -> Result<Self, S::Error> {
165 scanner.scan_name()
166 }
167
168 #[must_use]
179 pub fn root() -> Self
180 where
181 Octs: From<&'static [u8]>,
182 {
183 unsafe { Self::from_octets_unchecked(b"\0".as_ref().into()) }
184 }
185
186 pub fn reverse_from_addr(addr: IpAddr) -> Result<Self, PushError>
191 where
192 Octs: FromBuilder,
193 <Octs as FromBuilder>::Builder: EmptyBuilder
194 + FreezeBuilder<Octets = Octs>
195 + AsRef<[u8]>
196 + AsMut<[u8]>,
197 {
198 let mut builder =
199 NameBuilder::<<Octs as FromBuilder>::Builder>::new();
200 match addr {
201 IpAddr::V4(addr) => {
202 let [a, b, c, d] = addr.octets();
203 builder.append_dec_u8_label(d)?;
204 builder.append_dec_u8_label(c)?;
205 builder.append_dec_u8_label(b)?;
206 builder.append_dec_u8_label(a)?;
207 builder.append_label(b"in-addr")?;
208 builder.append_label(b"arpa")?;
209 }
210 IpAddr::V6(addr) => {
211 for &item in addr.octets().iter().rev() {
212 builder.append_hex_digit_label(item)?;
213 builder.append_hex_digit_label(item >> 4)?;
214 }
215 builder.append_label(b"ip6")?;
216 builder.append_label(b"arpa")?;
217 }
218 }
219 builder.into_name()
220 }
221}
222
223impl Name<[u8]> {
224 unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
226 mem::transmute(slice)
228 }
229
230 pub fn from_slice(slice: &[u8]) -> Result<&Self, NameError> {
246 Self::check_slice(slice)?;
247 Ok(unsafe { Self::from_slice_unchecked(slice) })
248 }
249
250 #[must_use]
252 pub fn root_slice() -> &'static Self {
253 unsafe { Self::from_slice_unchecked("\0".as_ref()) }
254 }
255
256 fn check_slice(mut slice: &[u8]) -> Result<(), NameError> {
258 if slice.len() > Name::MAX_LEN {
259 return Err(NameError(DnameErrorEnum::LongName));
260 }
261 loop {
262 let (label, tail) = Label::split_from(slice)?;
263 if label.is_root() {
264 if tail.is_empty() {
265 break;
266 } else {
267 return Err(NameError(DnameErrorEnum::TrailingData));
268 }
269 }
270 if tail.is_empty() {
271 return Err(NameError(DnameErrorEnum::RelativeName));
272 }
273 slice = tail;
274 }
275 Ok(())
276 }
277}
278
279impl Name<&'static [u8]> {
280 #[must_use]
282 pub fn root_ref() -> Self {
283 Self::root()
284 }
285}
286
287#[cfg(feature = "std")]
288impl Name<Vec<u8>> {
289 #[must_use]
291 pub fn root_vec() -> Self {
292 Self::root()
293 }
294
295 pub fn vec_from_str(s: &str) -> Result<Self, FromStrError> {
297 FromStr::from_str(s)
298 }
299}
300
301#[cfg(feature = "bytes")]
302impl Name<Bytes> {
303 pub fn root_bytes() -> Self {
305 Self::root()
306 }
307
308 pub fn bytes_from_str(s: &str) -> Result<Self, FromStrError> {
310 FromStr::from_str(s)
311 }
312}
313
314impl<Octs: ?Sized> Name<Octs> {
317 pub fn as_octets(&self) -> &Octs {
321 &self.0
322 }
323
324 pub fn into_octets(self) -> Octs
326 where
327 Octs: Sized,
328 {
329 self.0
330 }
331
332 pub fn into_relative(mut self) -> RelativeName<Octs>
334 where
335 Octs: Sized + AsRef<[u8]> + Truncate,
336 {
337 let len = self.0.as_ref().len() - 1;
338 self.0.truncate(len);
339 unsafe { RelativeName::from_octets_unchecked(self.0) }
340 }
341
342 pub fn for_ref(&self) -> Name<&Octs> {
344 unsafe { Name::from_octets_unchecked(&self.0) }
345 }
346
347 pub fn as_slice(&self) -> &[u8]
351 where
352 Octs: AsRef<[u8]>,
353 {
354 self.0.as_ref()
355 }
356
357 pub fn for_slice(&self) -> &Name<[u8]>
359 where
360 Octs: AsRef<[u8]>,
361 {
362 unsafe { Name::from_slice_unchecked(self.0.as_ref()) }
363 }
364
365 pub fn make_canonical(&mut self)
370 where
371 Octs: AsMut<[u8]>,
372 {
373 Label::make_slice_canonical(self.0.as_mut());
374 }
375}
376
377impl<Octs: AsRef<[u8]> + ?Sized> Name<Octs> {
380 pub fn is_root(&self) -> bool {
382 self.0.as_ref().len() == 1
383 }
384
385 #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize {
388 self.0.as_ref().len()
389 }
390
391 pub fn fmt_with_dot(&self) -> impl fmt::Display + '_ {
398 ToName::fmt_with_dot(self)
399 }
400}
401
402impl<Octs: AsRef<[u8]> + ?Sized> Name<Octs> {
405 pub fn iter(&self) -> NameIter {
407 NameIter::new(self.0.as_ref())
408 }
409
410 pub fn iter_suffixes(&self) -> SuffixIter<'_, Octs> {
416 SuffixIter::new(self)
417 }
418
419 pub fn label_count(&self) -> usize {
421 self.iter().count()
422 }
423
424 pub fn first(&self) -> &Label {
426 self.iter().next().unwrap()
427 }
428
429 pub fn last(&self) -> &'static Label {
435 Label::root()
436 }
437
438 pub fn starts_with<'a, N: ToLabelIter + ?Sized>(
440 &'a self,
441 base: &'a N,
442 ) -> bool {
443 <Self as ToLabelIter>::starts_with(self, base)
444 }
445
446 pub fn ends_with<'a, N: ToLabelIter + ?Sized>(
448 &'a self,
449 base: &'a N,
450 ) -> bool {
451 <Self as ToLabelIter>::ends_with(self, base)
452 }
453
454 pub fn is_label_start(&self, mut index: usize) -> bool {
456 if index == 0 {
457 return true;
458 }
459 let mut tmp = self.as_slice();
460 while !tmp.is_empty() {
461 let (label, tail) = Label::split_from(tmp).unwrap();
462 let len = label.len() + 1;
463 if index < len || len == 1 {
464 return false;
466 } else if index == len {
467 return true;
468 }
469 index -= len;
470 tmp = tail;
471 }
472 false
473 }
474
475 fn check_index(&self, index: usize) {
477 if !self.is_label_start(index) {
478 panic!("index not at start of a label");
479 }
480 }
481
482 fn check_bounds(&self, bounds: &impl RangeBounds<usize>) {
484 match bounds.start_bound().cloned() {
485 Bound::Included(idx) => self.check_index(idx),
486 Bound::Excluded(_) => {
487 panic!("excluded lower bounds not supported");
488 }
489 Bound::Unbounded => {}
490 }
491 match bounds.end_bound().cloned() {
492 Bound::Included(idx) => self
493 .check_index(idx.checked_add(1).expect("end bound too big")),
494 Bound::Excluded(idx) => self.check_index(idx),
495 Bound::Unbounded => {
496 panic!("unbounded end bound (results in absolute name)")
497 }
498 }
499 }
500
501 pub fn slice(
524 &self,
525 range: impl RangeBounds<usize>,
526 ) -> &RelativeName<[u8]> {
527 self.check_bounds(&range);
528 unsafe {
529 RelativeName::from_slice_unchecked(self.0.as_ref().range(range))
530 }
531 }
532
533 pub fn slice_from(&self, begin: usize) -> &Name<[u8]> {
551 self.check_index(begin);
552 unsafe { Name::from_slice_unchecked(&self.0.as_ref()[begin..]) }
553 }
554
555 pub fn range(
573 &self,
574 range: impl RangeBounds<usize>,
575 ) -> RelativeName<<Octs as Octets>::Range<'_>>
576 where
577 Octs: Octets,
578 {
579 self.check_bounds(&range);
580 unsafe { RelativeName::from_octets_unchecked(self.0.range(range)) }
581 }
582
583 pub fn range_from(
595 &self,
596 begin: usize,
597 ) -> Name<<Octs as Octets>::Range<'_>>
598 where
599 Octs: Octets,
600 {
601 self.check_index(begin);
602 unsafe { self.range_from_unchecked(begin) }
603 }
604
605 unsafe fn range_from_unchecked(
607 &self,
608 begin: usize,
609 ) -> Name<<Octs as Octets>::Range<'_>>
610 where
611 Octs: Octets,
612 {
613 Name::from_octets_unchecked(self.0.range(begin..))
614 }
615}
616
617impl<Octs: AsRef<[u8]> + ?Sized> Name<Octs> {
618 pub fn split(
627 &self,
628 mid: usize,
629 ) -> (RelativeName<Octs::Range<'_>>, Name<Octs::Range<'_>>)
630 where
631 Octs: Octets,
632 {
633 self.check_index(mid);
634 unsafe {
635 (
636 RelativeName::from_octets_unchecked(self.0.range(..mid)),
637 Name::from_octets_unchecked(self.0.range(mid..)),
638 )
639 }
640 }
641
642 pub fn truncate(mut self, len: usize) -> RelativeName<Octs>
652 where
653 Octs: Truncate + Sized,
654 {
655 self.check_index(len);
656 self.0.truncate(len);
657 unsafe { RelativeName::from_octets_unchecked(self.0) }
658 }
659
660 pub fn split_first(&self) -> Option<(&Label, Name<Octs::Range<'_>>)>
666 where
667 Octs: Octets,
668 {
669 if self.compose_len() == 1 {
670 return None;
671 }
672 let label = self.iter().next().unwrap();
673 Some((label, self.split(label.len() + 1).1))
674 }
675
676 pub fn parent(&self) -> Option<Name<Octs::Range<'_>>>
680 where
681 Octs: Octets,
682 {
683 self.split_first().map(|(_, parent)| parent)
684 }
685
686 pub fn strip_suffix<N: ToName + ?Sized>(
692 self,
693 base: &N,
694 ) -> Result<RelativeName<Octs>, Self>
695 where
696 Octs: Truncate + Sized,
697 {
698 if self.ends_with(base) {
699 let len = self.0.as_ref().len() - usize::from(base.compose_len());
700 Ok(self.truncate(len))
701 } else {
702 Err(self)
703 }
704 }
705}
706
707impl<Octs> Name<Octs> {
708 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
710 parser: &mut Parser<'a, Src>,
711 ) -> Result<Self, ParseError> {
712 let len = Self::parse_name_len(parser)?;
713 Ok(unsafe { Self::from_octets_unchecked(parser.parse_octets(len)?) })
714 }
715
716 fn parse_name_len<Source: AsRef<[u8]> + ?Sized>(
718 parser: &Parser<Source>,
719 ) -> Result<usize, ParseError> {
720 let len = {
721 let mut tmp = parser.peek_all();
722 loop {
723 if tmp.is_empty() {
724 return Err(ParseError::ShortInput);
725 }
726 let (label, tail) = Label::split_from(tmp)?;
727 tmp = tail;
728 if label.is_root() {
729 break;
730 }
731 }
732 parser.remaining() - tmp.len()
733 };
734 if len > Name::MAX_LEN {
735 Err(NameError(DnameErrorEnum::LongName).into())
736 } else {
737 Ok(len)
738 }
739 }
740}
741
742impl<Octs> AsRef<Octs> for Name<Octs> {
745 fn as_ref(&self) -> &Octs {
746 &self.0
747 }
748}
749
750impl<Octs: AsRef<[u8]> + ?Sized> AsRef<[u8]> for Name<Octs> {
751 fn as_ref(&self) -> &[u8] {
752 self.0.as_ref()
753 }
754}
755
756impl<Octs, SrcOcts> OctetsFrom<Name<SrcOcts>> for Name<Octs>
759where
760 Octs: OctetsFrom<SrcOcts>,
761{
762 type Error = Octs::Error;
763
764 fn try_octets_from(source: Name<SrcOcts>) -> Result<Self, Self::Error> {
765 Octs::try_octets_from(source.0)
766 .map(|octets| unsafe { Self::from_octets_unchecked(octets) })
767 }
768}
769
770impl<Octs> FromStr for Name<Octs>
773where
774 Octs: FromBuilder,
775 <Octs as FromBuilder>::Builder: EmptyBuilder
776 + FreezeBuilder<Octets = Octs>
777 + AsRef<[u8]>
778 + AsMut<[u8]>,
779{
780 type Err = FromStrError;
781
782 fn from_str(s: &str) -> Result<Self, Self::Err> {
795 Self::from_chars(s.chars())
796 }
797}
798
799impl<Octs, Target> FlattenInto<Name<Target>> for Name<Octs>
802where
803 Target: OctetsFrom<Octs>,
804{
805 type AppendError = Target::Error;
806
807 fn try_flatten_into(self) -> Result<Name<Target>, Self::AppendError> {
808 Target::try_octets_from(self.0)
809 .map(|octets| unsafe { Name::from_octets_unchecked(octets) })
810 }
811}
812
813impl<Octs, N> PartialEq<N> for Name<Octs>
816where
817 Octs: AsRef<[u8]> + ?Sized,
818 N: ToName + ?Sized,
819{
820 fn eq(&self, other: &N) -> bool {
821 self.name_eq(other)
822 }
823}
824
825impl<Octs: AsRef<[u8]> + ?Sized> Eq for Name<Octs> {}
826
827impl<Octs, N> PartialOrd<N> for Name<Octs>
830where
831 Octs: AsRef<[u8]> + ?Sized,
832 N: ToName + ?Sized,
833{
834 fn partial_cmp(&self, other: &N) -> Option<cmp::Ordering> {
841 Some(self.name_cmp(other))
842 }
843}
844
845impl<Octs: AsRef<[u8]> + ?Sized> Ord for Name<Octs> {
846 fn cmp(&self, other: &Self) -> cmp::Ordering {
853 self.name_cmp(other)
854 }
855}
856
857impl<Octs, N> CanonicalOrd<N> for Name<Octs>
858where
859 Octs: AsRef<[u8]> + ?Sized,
860 N: ToName + ?Sized,
861{
862 fn canonical_cmp(&self, other: &N) -> cmp::Ordering {
863 self.name_cmp(other)
864 }
865}
866
867impl<Octs: AsRef<[u8]> + ?Sized> hash::Hash for Name<Octs> {
870 fn hash<H: hash::Hasher>(&self, state: &mut H) {
871 for item in self.iter() {
872 item.hash(state)
873 }
874 }
875}
876
877impl<Octs> ToLabelIter for Name<Octs>
880where
881 Octs: AsRef<[u8]> + ?Sized,
882{
883 type LabelIter<'a>
884 = NameIter<'a>
885 where
886 Octs: 'a;
887
888 fn iter_labels(&self) -> Self::LabelIter<'_> {
889 self.iter()
890 }
891
892 fn compose_len(&self) -> u16 {
893 u16::try_from(self.0.as_ref().len()).expect("long domain name")
894 }
895}
896
897impl<Octs: AsRef<[u8]> + ?Sized> ToName for Name<Octs> {
898 fn as_flat_slice(&self) -> Option<&[u8]> {
899 Some(self.0.as_ref())
900 }
901}
902
903impl<'a, Octs> IntoIterator for &'a Name<Octs>
906where
907 Octs: AsRef<[u8]> + ?Sized,
908{
909 type Item = &'a Label;
910 type IntoIter = NameIter<'a>;
911
912 fn into_iter(self) -> Self::IntoIter {
913 self.iter()
914 }
915}
916
917impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for Name<Octs> {
920 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
926 if self.is_root() {
927 return f.write_str(".");
928 }
929
930 let mut iter = self.iter();
931 write!(f, "{}", iter.next().unwrap())?;
932 for label in iter {
933 if !label.is_root() {
934 write!(f, ".{}", label)?
935 }
936 }
937 Ok(())
938 }
939}
940
941impl<Octs: AsRef<[u8]> + ?Sized> fmt::Debug for Name<Octs> {
944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945 write!(f, "Name({})", self.fmt_with_dot())
946 }
947}
948
949impl<Octs: AsRef<[u8]>> AsRef<Name<[u8]>> for Name<Octs> {
952 fn as_ref(&self) -> &Name<[u8]> {
953 self.for_slice()
954 }
955}
956
957impl<Octs: AsRef<[u8]>> borrow::Borrow<Name<[u8]>> for Name<Octs> {
977 fn borrow(&self) -> &Name<[u8]> {
978 self.for_slice()
979 }
980}
981
982#[cfg(feature = "serde")]
985impl<Octs> serde::Serialize for Name<Octs>
986where
987 Octs: AsRef<[u8]> + SerializeOctets + ?Sized,
988{
989 fn serialize<S: serde::Serializer>(
990 &self,
991 serializer: S,
992 ) -> Result<S::Ok, S::Error> {
993 if serializer.is_human_readable() {
994 serializer
995 .serialize_newtype_struct("Name", &format_args!("{}", self))
996 } else {
997 serializer.serialize_newtype_struct(
998 "Name",
999 &self.0.as_serialized_octets(),
1000 )
1001 }
1002 }
1003}
1004
1005#[cfg(feature = "serde")]
1006impl<'de, Octs> serde::Deserialize<'de> for Name<Octs>
1007where
1008 Octs: FromBuilder + DeserializeOctets<'de>,
1009 <Octs as FromBuilder>::Builder: FreezeBuilder<Octets = Octs>
1010 + EmptyBuilder
1011 + AsRef<[u8]>
1012 + AsMut<[u8]>,
1013{
1014 fn deserialize<D: serde::Deserializer<'de>>(
1015 deserializer: D,
1016 ) -> Result<Self, D::Error> {
1017 use core::marker::PhantomData;
1018
1019 struct InnerVisitor<'de, T: DeserializeOctets<'de>>(T::Visitor);
1020
1021 impl<'de, Octs> serde::de::Visitor<'de> for InnerVisitor<'de, Octs>
1022 where
1023 Octs: FromBuilder + DeserializeOctets<'de>,
1024 <Octs as FromBuilder>::Builder: FreezeBuilder<Octets = Octs>
1025 + EmptyBuilder
1026 + AsRef<[u8]>
1027 + AsMut<[u8]>,
1028 {
1029 type Value = Name<Octs>;
1030
1031 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1032 f.write_str("an absolute domain name")
1033 }
1034
1035 fn visit_str<E: serde::de::Error>(
1036 self,
1037 v: &str,
1038 ) -> Result<Self::Value, E> {
1039 Name::from_str(v).map_err(E::custom)
1040 }
1041
1042 fn visit_borrowed_bytes<E: serde::de::Error>(
1043 self,
1044 value: &'de [u8],
1045 ) -> Result<Self::Value, E> {
1046 self.0.visit_borrowed_bytes(value).and_then(|octets| {
1047 Name::from_octets(octets).map_err(E::custom)
1048 })
1049 }
1050
1051 #[cfg(feature = "std")]
1052 fn visit_byte_buf<E: serde::de::Error>(
1053 self,
1054 value: std::vec::Vec<u8>,
1055 ) -> Result<Self::Value, E> {
1056 self.0.visit_byte_buf(value).and_then(|octets| {
1057 Name::from_octets(octets).map_err(E::custom)
1058 })
1059 }
1060 }
1061
1062 struct NewtypeVisitor<T>(PhantomData<T>);
1063
1064 impl<'de, Octs> serde::de::Visitor<'de> for NewtypeVisitor<Octs>
1065 where
1066 Octs: FromBuilder + DeserializeOctets<'de>,
1067 <Octs as FromBuilder>::Builder: EmptyBuilder
1068 + FreezeBuilder<Octets = Octs>
1069 + AsRef<[u8]>
1070 + AsMut<[u8]>,
1071 {
1072 type Value = Name<Octs>;
1073
1074 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1075 f.write_str("an absolute domain name")
1076 }
1077
1078 fn visit_newtype_struct<D: serde::Deserializer<'de>>(
1079 self,
1080 deserializer: D,
1081 ) -> Result<Self::Value, D::Error> {
1082 if deserializer.is_human_readable() {
1083 deserializer
1084 .deserialize_str(InnerVisitor(Octs::visitor()))
1085 } else {
1086 Octs::deserialize_with_visitor(
1087 deserializer,
1088 InnerVisitor(Octs::visitor()),
1089 )
1090 }
1091 }
1092 }
1093
1094 deserializer
1095 .deserialize_newtype_struct("Name", NewtypeVisitor(PhantomData))
1096 }
1097}
1098
1099#[derive(Clone)]
1103pub struct SuffixIter<'a, Octs: ?Sized> {
1104 name: &'a Name<Octs>,
1105 start: Option<usize>,
1106}
1107
1108impl<'a, Octs: ?Sized> SuffixIter<'a, Octs> {
1109 fn new(name: &'a Name<Octs>) -> Self {
1111 SuffixIter {
1112 name,
1113 start: Some(0),
1114 }
1115 }
1116}
1117
1118impl<'a, Octs: Octets + ?Sized> Iterator for SuffixIter<'a, Octs> {
1119 type Item = Name<Octs::Range<'a>>;
1120
1121 fn next(&mut self) -> Option<Self::Item> {
1122 let start = self.start?;
1123 let res = unsafe { self.name.range_from_unchecked(start) };
1124 let label = res.first();
1125 if label.is_root() {
1126 self.start = None;
1127 } else {
1128 self.start = Some(start + usize::from(label.compose_len()))
1129 }
1130 Some(res)
1131 }
1132}
1133
1134#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1140pub struct NameError(DnameErrorEnum);
1141
1142#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1143enum DnameErrorEnum {
1144 BadLabel(LabelTypeError),
1146
1147 CompressedName,
1149
1150 LongName,
1152
1153 RelativeName,
1155
1156 TrailingData,
1158
1159 ShortInput,
1161}
1162
1163impl From<LabelTypeError> for NameError {
1166 fn from(err: LabelTypeError) -> Self {
1167 Self(DnameErrorEnum::BadLabel(err))
1168 }
1169}
1170
1171impl From<SplitLabelError> for NameError {
1172 fn from(err: SplitLabelError) -> Self {
1173 Self(match err {
1174 SplitLabelError::Pointer(_) => DnameErrorEnum::CompressedName,
1175 SplitLabelError::BadType(t) => DnameErrorEnum::BadLabel(t),
1176 SplitLabelError::ShortInput => DnameErrorEnum::ShortInput,
1177 })
1178 }
1179}
1180
1181impl From<NameError> for FormError {
1182 fn from(err: NameError) -> FormError {
1183 FormError::new(match err.0 {
1184 DnameErrorEnum::BadLabel(_) => "unknown label type",
1185 DnameErrorEnum::CompressedName => "compressed domain name",
1186 DnameErrorEnum::LongName => "long domain name",
1187 DnameErrorEnum::RelativeName => "relative domain name",
1188 DnameErrorEnum::TrailingData => "trailing data in buffer",
1189 DnameErrorEnum::ShortInput => "unexpected end of buffer",
1190 })
1191 }
1192}
1193
1194impl From<NameError> for ParseError {
1195 fn from(err: NameError) -> ParseError {
1196 match err.0 {
1197 DnameErrorEnum::ShortInput => ParseError::ShortInput,
1198 _ => ParseError::Form(err.into()),
1199 }
1200 }
1201}
1202
1203impl fmt::Display for NameError {
1206 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1207 match self.0 {
1208 DnameErrorEnum::BadLabel(ref err) => err.fmt(f),
1209 DnameErrorEnum::CompressedName => {
1210 f.write_str("compressed domain name")
1211 }
1212 DnameErrorEnum::LongName => f.write_str("long domain name"),
1213 DnameErrorEnum::RelativeName => f.write_str("relative name"),
1214 DnameErrorEnum::TrailingData => f.write_str("trailing data"),
1215 DnameErrorEnum::ShortInput => ParseError::ShortInput.fmt(f),
1216 }
1217 }
1218}
1219
1220#[cfg(feature = "std")]
1221impl std::error::Error for NameError {}
1222
1223#[cfg(test)]
1229pub(crate) mod test {
1230 use super::*;
1231
1232 #[cfg(feature = "std")]
1233 macro_rules! assert_panic {
1234 ( $cond:expr ) => {{
1235 let result = std::panic::catch_unwind(|| $cond);
1236 assert!(result.is_err());
1237 }};
1238 }
1239
1240 #[test]
1241 fn impls() {
1242 fn assert_to_name<T: ToName + ?Sized>(_: &T) {}
1243
1244 assert_to_name(Name::from_slice(b"\0".as_ref()).unwrap());
1245 assert_to_name(&Name::from_octets(b"\0").unwrap());
1246 assert_to_name(&Name::from_octets(b"\0".as_ref()).unwrap());
1247
1248 #[cfg(feature = "std")]
1249 {
1250 assert_to_name(
1251 &Name::from_octets(Vec::from(b"\0".as_ref())).unwrap(),
1252 );
1253 }
1254 }
1255
1256 #[cfg(feature = "bytes")]
1257 #[test]
1258 fn impls_bytes() {
1259 fn assert_to_name<T: ToName + ?Sized>(_: &T) {}
1260
1261 assert_to_name(
1262 &Name::from_octets(Bytes::from(b"\0".as_ref())).unwrap(),
1263 );
1264 }
1265
1266 #[test]
1267 fn root() {
1268 assert_eq!(Name::root_ref().as_slice(), b"\0");
1269 #[cfg(feature = "std")]
1270 {
1271 assert_eq!(Name::root_vec().as_slice(), b"\0");
1272 }
1273 assert_eq!(Name::root_slice().as_slice(), b"\0");
1274 }
1275
1276 #[cfg(feature = "bytes")]
1277 #[test]
1278 fn root_bytes() {
1279 assert_eq!(Name::root_bytes().as_slice(), b"\0");
1280 }
1281
1282 #[test]
1283 #[cfg(feature = "std")]
1284 fn from_slice() {
1285 assert_eq!(
1287 Name::from_slice(b"\x03www\x07example\x03com\0")
1288 .unwrap()
1289 .as_slice(),
1290 b"\x03www\x07example\x03com\0"
1291 );
1292
1293 assert_eq!(
1295 Name::from_slice(b"\x03www\x07example\x03com"),
1296 Err(NameError(DnameErrorEnum::RelativeName))
1297 );
1298
1299 assert_eq!(
1301 Name::from_slice(b"\x03www\x07exa"),
1302 Err(NameError(DnameErrorEnum::ShortInput))
1303 );
1304
1305 let mut slice = [0u8; 65];
1307 slice[0] = 63;
1308 assert!(Name::from_slice(&slice[..]).is_ok());
1309 let mut slice = [0u8; 66];
1310 slice[0] = 64;
1311 assert!(Name::from_slice(&slice[..]).is_err());
1312
1313 let mut buf = std::vec::Vec::new();
1315 for _ in 0..25 {
1316 buf.extend_from_slice(b"\x09123456789");
1317 }
1318 assert_eq!(buf.len(), 250);
1319 let mut tmp = buf.clone();
1320 tmp.extend_from_slice(b"\x03123\0");
1321 assert_eq!(Name::from_slice(&tmp).map(|_| ()), Ok(()));
1322 buf.extend_from_slice(b"\x041234\0");
1323 assert!(Name::from_slice(&buf).is_err());
1324
1325 assert!(Name::from_slice(b"\x03com\0\x03www\0").is_err());
1327
1328 assert_eq!(
1330 Name::from_slice(b"\xa2asdasds"),
1331 Err(LabelTypeError::Undefined.into())
1332 );
1333 assert_eq!(
1334 Name::from_slice(b"\x62asdasds"),
1335 Err(LabelTypeError::Extended(0x62).into())
1336 );
1337 assert_eq!(
1338 Name::from_slice(b"\xccasdasds"),
1339 Err(NameError(DnameErrorEnum::CompressedName))
1340 );
1341
1342 assert_eq!(
1344 Name::from_slice(b""),
1345 Err(NameError(DnameErrorEnum::ShortInput))
1346 );
1347 }
1348
1349 #[test]
1350 fn test_dname_from_addr() {
1351 type TestName = Name<octseq::array::Array<128>>;
1352
1353 assert_eq!(
1354 TestName::reverse_from_addr([192, 0, 2, 12].into()).unwrap(),
1355 TestName::from_str("12.2.0.192.in-addr.arpa").unwrap()
1356 );
1357 assert_eq!(
1358 TestName::reverse_from_addr(
1359 [0x2001, 0xdb8, 0x1234, 0x0, 0x5678, 0x1, 0x9abc, 0xdef]
1360 .into()
1361 )
1362 .unwrap(),
1363 TestName::from_str(
1364 "f.e.d.0.c.b.a.9.1.0.0.0.8.7.6.5.\
1365 0.0.0.0.4.3.2.1.8.b.d.0.1.0.0.2.\
1366 ip6.arpa"
1367 )
1368 .unwrap()
1369 );
1370 }
1371 #[test]
1376 fn into_relative() {
1377 assert_eq!(
1378 Name::from_octets(b"\x03www\0".as_ref())
1379 .unwrap()
1380 .into_relative()
1381 .as_slice(),
1382 b"\x03www"
1383 );
1384 }
1385
1386 #[test]
1387 #[cfg(feature = "std")]
1388 fn make_canonical() {
1389 let mut name = RelativeName::vec_from_str("wWw.exAmpLE.coM").unwrap();
1390 name.make_canonical();
1391 assert_eq!(
1392 name,
1393 RelativeName::from_octets(b"\x03www\x07example\x03com").unwrap()
1394 );
1395 }
1396
1397 #[test]
1398 fn is_root() {
1399 assert!(Name::from_slice(b"\0").unwrap().is_root());
1400 assert!(!Name::from_slice(b"\x03www\0").unwrap().is_root());
1401 assert!(Name::root_ref().is_root());
1402 }
1403
1404 pub fn cmp_iter<I>(mut iter: I, labels: &[&[u8]])
1405 where
1406 I: Iterator,
1407 I::Item: AsRef<[u8]>,
1408 {
1409 let mut labels = labels.iter();
1410 loop {
1411 match (iter.next(), labels.next()) {
1412 (Some(left), Some(right)) => {
1413 assert_eq!(left.as_ref(), *right)
1414 }
1415 (None, None) => break,
1416 (_, None) => panic!("extra items in iterator"),
1417 (None, _) => panic!("missing items in iterator"),
1418 }
1419 }
1420 }
1421
1422 #[test]
1423 fn iter() {
1424 cmp_iter(Name::root_ref().iter(), &[b""]);
1425 cmp_iter(
1426 Name::from_slice(b"\x03www\x07example\x03com\0")
1427 .unwrap()
1428 .iter(),
1429 &[b"www", b"example", b"com", b""],
1430 );
1431 }
1432
1433 pub fn cmp_iter_back<I>(mut iter: I, labels: &[&[u8]])
1434 where
1435 I: DoubleEndedIterator,
1436 I::Item: AsRef<[u8]>,
1437 {
1438 let mut labels = labels.iter();
1439 loop {
1440 match (iter.next_back(), labels.next()) {
1441 (Some(left), Some(right)) => {
1442 assert_eq!(left.as_ref(), *right)
1443 }
1444 (None, None) => break,
1445 (_, None) => panic!("extra items in iterator"),
1446 (None, _) => panic!("missing items in iterator"),
1447 }
1448 }
1449 }
1450
1451 #[test]
1452 fn iter_back() {
1453 cmp_iter_back(Name::root_ref().iter(), &[b""]);
1454 cmp_iter_back(
1455 Name::from_slice(b"\x03www\x07example\x03com\0")
1456 .unwrap()
1457 .iter(),
1458 &[b"", b"com", b"example", b"www"],
1459 );
1460 }
1461
1462 #[test]
1463 fn iter_suffixes() {
1464 cmp_iter(Name::root_ref().iter_suffixes(), &[b"\0"]);
1465 cmp_iter(
1466 Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1467 .unwrap()
1468 .iter_suffixes(),
1469 &[
1470 b"\x03www\x07example\x03com\0",
1471 b"\x07example\x03com\0",
1472 b"\x03com\0",
1473 b"\0",
1474 ],
1475 );
1476 }
1477
1478 #[test]
1479 fn label_count() {
1480 assert_eq!(Name::root_ref().label_count(), 1);
1481 assert_eq!(
1482 Name::from_slice(b"\x03www\x07example\x03com\0")
1483 .unwrap()
1484 .label_count(),
1485 4
1486 );
1487 }
1488
1489 #[test]
1490 fn first() {
1491 assert_eq!(Name::root_ref().first().as_slice(), b"");
1492 assert_eq!(
1493 Name::from_slice(b"\x03www\x07example\x03com\0")
1494 .unwrap()
1495 .first()
1496 .as_slice(),
1497 b"www"
1498 );
1499 }
1500
1501 #[test]
1502 fn last() {
1503 assert_eq!(Name::root_ref().last().as_slice(), b"");
1504 assert_eq!(
1505 Name::from_slice(b"\x03www\x07example\x03com\0")
1506 .unwrap()
1507 .last()
1508 .as_slice(),
1509 b""
1510 );
1511 }
1512
1513 #[test]
1514 fn starts_with() {
1515 let root = Name::root_ref();
1516 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1517 .unwrap();
1518
1519 assert!(root.starts_with(&root));
1520 assert!(wecr.starts_with(&wecr));
1521
1522 assert!(root.starts_with(&RelativeName::empty_ref()));
1523 assert!(wecr.starts_with(&RelativeName::empty_ref()));
1524
1525 let test = RelativeName::from_slice(b"\x03www").unwrap();
1526 assert!(!root.starts_with(&test));
1527 assert!(wecr.starts_with(&test));
1528
1529 let test = RelativeName::from_slice(b"\x03www\x07example").unwrap();
1530 assert!(!root.starts_with(&test));
1531 assert!(wecr.starts_with(&test));
1532
1533 let test =
1534 RelativeName::from_slice(b"\x03www\x07example\x03com").unwrap();
1535 assert!(!root.starts_with(&test));
1536 assert!(wecr.starts_with(&test));
1537
1538 let test = RelativeName::from_slice(b"\x07example\x03com").unwrap();
1539 assert!(!root.starts_with(&test));
1540 assert!(!wecr.starts_with(&test));
1541
1542 let test = RelativeName::from_octets(b"\x03www".as_ref())
1543 .unwrap()
1544 .chain(
1545 RelativeName::from_octets(b"\x07example".as_ref()).unwrap(),
1546 )
1547 .unwrap();
1548 assert!(!root.starts_with(&test));
1549 assert!(wecr.starts_with(&test));
1550
1551 let test = test
1552 .chain(RelativeName::from_octets(b"\x03com".as_ref()).unwrap())
1553 .unwrap();
1554 assert!(!root.starts_with(&test));
1555 assert!(wecr.starts_with(&test));
1556 }
1557
1558 #[test]
1559 fn ends_with() {
1560 let root = Name::root_ref();
1561 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1562 .unwrap();
1563
1564 for name in wecr.iter_suffixes() {
1565 if name.is_root() {
1566 assert!(root.ends_with(&name));
1567 } else {
1568 assert!(!root.ends_with(&name));
1569 }
1570 assert!(wecr.ends_with(&name));
1571 }
1572 }
1573
1574 #[test]
1575 fn is_label_start() {
1576 let wecr = Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1577
1578 assert!(wecr.is_label_start(0)); assert!(!wecr.is_label_start(1)); assert!(!wecr.is_label_start(2)); assert!(!wecr.is_label_start(3)); assert!(wecr.is_label_start(4)); assert!(!wecr.is_label_start(5)); assert!(!wecr.is_label_start(6)); assert!(!wecr.is_label_start(7)); assert!(!wecr.is_label_start(8)); assert!(!wecr.is_label_start(9)); assert!(!wecr.is_label_start(10)); assert!(!wecr.is_label_start(11)); assert!(wecr.is_label_start(12)); assert!(!wecr.is_label_start(13)); assert!(!wecr.is_label_start(14)); assert!(!wecr.is_label_start(15)); assert!(wecr.is_label_start(16)); assert!(!wecr.is_label_start(17)); assert!(!wecr.is_label_start(18)); }
1598
1599 #[test]
1600 #[cfg(feature = "std")]
1601 fn slice() {
1602 let wecr = Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1603
1604 assert_eq!(wecr.slice(..4).as_slice(), b"\x03www");
1605 assert_eq!(wecr.slice(..12).as_slice(), b"\x03www\x07example");
1606 assert_eq!(wecr.slice(4..12).as_slice(), b"\x07example");
1607 assert_eq!(wecr.slice(4..16).as_slice(), b"\x07example\x03com");
1608
1609 assert_panic!(wecr.slice(0..3));
1610 assert_panic!(wecr.slice(1..4));
1611 assert_panic!(wecr.slice(0..11));
1612 assert_panic!(wecr.slice(1..12));
1613 assert_panic!(wecr.slice(0..17));
1614 assert_panic!(wecr.slice(4..17));
1615 assert_panic!(wecr.slice(0..18));
1616 }
1617
1618 #[test]
1619 #[cfg(feature = "std")]
1620 fn slice_from() {
1621 let wecr = Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1622
1623 assert_eq!(
1624 wecr.slice_from(0).as_slice(),
1625 b"\x03www\x07example\x03com\0"
1626 );
1627 assert_eq!(wecr.slice_from(4).as_slice(), b"\x07example\x03com\0");
1628 assert_eq!(wecr.slice_from(12).as_slice(), b"\x03com\0");
1629 assert_eq!(wecr.slice_from(16).as_slice(), b"\0");
1630
1631 assert_panic!(wecr.slice_from(17));
1632 assert_panic!(wecr.slice_from(18));
1633 }
1634
1635 #[test]
1636 #[cfg(feature = "std")]
1637 fn range() {
1638 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1639 .unwrap();
1640
1641 assert_eq!(wecr.range(0..4).as_slice(), b"\x03www");
1642 assert_eq!(wecr.range(0..12).as_slice(), b"\x03www\x07example");
1643 assert_eq!(wecr.range(4..12).as_slice(), b"\x07example");
1644 assert_eq!(wecr.range(4..16).as_slice(), b"\x07example\x03com");
1645
1646 assert_panic!(wecr.range(0..3));
1647 assert_panic!(wecr.range(1..4));
1648 assert_panic!(wecr.range(0..11));
1649 assert_panic!(wecr.range(1..12));
1650 assert_panic!(wecr.range(0..17));
1651 assert_panic!(wecr.range(4..17));
1652 assert_panic!(wecr.range(0..18));
1653 }
1654
1655 #[test]
1656 #[cfg(feature = "std")]
1657 fn range_from() {
1658 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1659 .unwrap();
1660
1661 assert_eq!(
1662 wecr.range_from(0).as_slice(),
1663 b"\x03www\x07example\x03com\0"
1664 );
1665 assert_eq!(wecr.range_from(4).as_slice(), b"\x07example\x03com\0");
1666 assert_eq!(wecr.range_from(12).as_slice(), b"\x03com\0");
1667 assert_eq!(wecr.range_from(16).as_slice(), b"\0");
1668
1669 assert_panic!(wecr.range_from(17));
1670 assert_panic!(wecr.range_from(18));
1671 }
1672
1673 #[test]
1674 #[cfg(feature = "std")]
1675 fn split() {
1676 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1677 .unwrap();
1678
1679 let (left, right) = wecr.split(0);
1680 assert_eq!(left.as_slice(), b"");
1681 assert_eq!(right.as_slice(), b"\x03www\x07example\x03com\0");
1682
1683 let (left, right) = wecr.split(4);
1684 assert_eq!(left.as_slice(), b"\x03www");
1685 assert_eq!(right.as_slice(), b"\x07example\x03com\0");
1686
1687 let (left, right) = wecr.split(12);
1688 assert_eq!(left.as_slice(), b"\x03www\x07example");
1689 assert_eq!(right.as_slice(), b"\x03com\0");
1690
1691 let (left, right) = wecr.split(16);
1692 assert_eq!(left.as_slice(), b"\x03www\x07example\x03com");
1693 assert_eq!(right.as_slice(), b"\0");
1694
1695 assert_panic!(wecr.split(1));
1696 assert_panic!(wecr.split(14));
1697 assert_panic!(wecr.split(17));
1698 assert_panic!(wecr.split(18));
1699 }
1700
1701 #[test]
1702 #[cfg(feature = "std")]
1703 fn truncate() {
1704 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1705 .unwrap();
1706
1707 assert_eq!(wecr.clone().truncate(0).as_slice(), b"");
1708 assert_eq!(wecr.clone().truncate(4).as_slice(), b"\x03www");
1709 assert_eq!(
1710 wecr.clone().truncate(12).as_slice(),
1711 b"\x03www\x07example"
1712 );
1713 assert_eq!(
1714 wecr.clone().truncate(16).as_slice(),
1715 b"\x03www\x07example\x03com"
1716 );
1717
1718 assert_panic!(wecr.clone().truncate(1));
1719 assert_panic!(wecr.clone().truncate(14));
1720 assert_panic!(wecr.clone().truncate(17));
1721 assert_panic!(wecr.clone().truncate(18));
1722 }
1723
1724 #[test]
1725 fn split_first() {
1726 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1727 .unwrap();
1728
1729 let (label, wecr) = wecr.split_first().unwrap();
1730 assert_eq!(label, b"www".as_ref());
1731 assert_eq!(wecr.as_slice(), b"\x07example\x03com\0");
1732
1733 let (label, wecr) = wecr.split_first().unwrap();
1734 assert_eq!(label, b"example");
1735 assert_eq!(wecr.as_slice(), b"\x03com\0");
1736
1737 let (label, wecr) = wecr.split_first().unwrap();
1738 assert_eq!(label, b"com");
1739 assert_eq!(wecr.as_slice(), b"\0");
1740 assert!(wecr.split_first().is_none());
1741 }
1742
1743 #[test]
1744 fn parent() {
1745 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1746 .unwrap();
1747
1748 let wecr = wecr.parent().unwrap();
1749 assert_eq!(wecr.as_slice(), b"\x07example\x03com\0");
1750 let wecr = wecr.parent().unwrap();
1751 assert_eq!(wecr.as_slice(), b"\x03com\0");
1752 let wecr = wecr.parent().unwrap();
1753 assert_eq!(wecr.as_slice(), b"\0");
1754 assert!(wecr.parent().is_none());
1755 }
1756
1757 #[test]
1758 fn strip_suffix() {
1759 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
1760 .unwrap();
1761 let ecr =
1762 Name::from_octets(b"\x07example\x03com\0".as_ref()).unwrap();
1763 let cr = Name::from_octets(b"\x03com\0".as_ref()).unwrap();
1764 let wenr = Name::from_octets(b"\x03www\x07example\x03net\0".as_ref())
1765 .unwrap();
1766 let enr =
1767 Name::from_octets(b"\x07example\x03net\0".as_ref()).unwrap();
1768 let nr = Name::from_octets(b"\x03net\0".as_ref()).unwrap();
1769
1770 assert_eq!(wecr.clone().strip_suffix(&wecr).unwrap().as_slice(), b"");
1771 assert_eq!(
1772 wecr.clone().strip_suffix(&ecr).unwrap().as_slice(),
1773 b"\x03www"
1774 );
1775 assert_eq!(
1776 wecr.clone().strip_suffix(&cr).unwrap().as_slice(),
1777 b"\x03www\x07example"
1778 );
1779 assert_eq!(
1780 wecr.clone()
1781 .strip_suffix(&Name::root_slice())
1782 .unwrap()
1783 .as_slice(),
1784 b"\x03www\x07example\x03com"
1785 );
1786
1787 assert_eq!(
1788 wecr.clone().strip_suffix(&wenr).unwrap_err().as_slice(),
1789 b"\x03www\x07example\x03com\0"
1790 );
1791 assert_eq!(
1792 wecr.clone().strip_suffix(&enr).unwrap_err().as_slice(),
1793 b"\x03www\x07example\x03com\0"
1794 );
1795 assert_eq!(
1796 wecr.clone().strip_suffix(&nr).unwrap_err().as_slice(),
1797 b"\x03www\x07example\x03com\0"
1798 );
1799 }
1800
1801 #[test]
1802 #[cfg(feature = "std")]
1803 fn parse() {
1804 let mut p = Parser::from_static(b"\x03www\x07example\x03com\0af");
1806 assert_eq!(
1807 Name::parse(&mut p).unwrap().as_slice(),
1808 b"\x03www\x07example\x03com\0"
1809 );
1810 assert_eq!(p.peek_all(), b"af");
1811
1812 let mut p = Parser::from_static(b"\x03www\x07exam");
1814 assert_eq!(Name::parse(&mut p), Err(ParseError::ShortInput));
1815
1816 let mut p = Parser::from_static(b"\x03www\x07example");
1818 assert_eq!(Name::parse(&mut p), Err(ParseError::ShortInput));
1819
1820 let mut p = Parser::from_static(b"\x03com\x03www\x07example\xc0\0");
1822 p.advance(4).unwrap();
1823 assert_eq!(
1824 Name::parse(&mut p),
1825 Err(NameError(DnameErrorEnum::CompressedName).into())
1826 );
1827
1828 let mut p = Parser::from_static(b"\x03www\x07example\xbffoo");
1830 assert!(Name::parse(&mut p).is_err());
1831
1832 let mut buf = Vec::new();
1834 for _ in 0..50 {
1835 buf.extend_from_slice(b"\x041234");
1836 }
1837 buf.extend_from_slice(b"\x03123\0");
1838 assert_eq!(buf.len(), 255);
1839 let mut p = Parser::from_ref(buf.as_slice());
1840 assert!(Name::parse(&mut p).is_ok());
1841 assert_eq!(p.peek_all(), b"");
1842
1843 let mut buf = Vec::new();
1845 for _ in 0..51 {
1846 buf.extend_from_slice(b"\x041234");
1847 }
1848 buf.extend_from_slice(b"\0");
1849 assert_eq!(buf.len(), 256);
1850 let mut p = Parser::from_ref(buf.as_slice());
1851 assert_eq!(
1852 Name::parse(&mut p),
1853 Err(NameError(DnameErrorEnum::LongName).into())
1854 );
1855 }
1856
1857 #[test]
1861 #[cfg(feature = "std")]
1862 fn compose_canonical() {
1863 use octseq::builder::infallible;
1864
1865 let mut buf = Vec::new();
1866 infallible(
1867 Name::from_slice(b"\x03wWw\x07exaMPle\x03com\0")
1868 .unwrap()
1869 .compose_canonical(&mut buf),
1870 );
1871 assert_eq!(buf.as_slice(), b"\x03www\x07example\x03com\0");
1872 }
1873
1874 #[test]
1875 #[cfg(feature = "std")]
1876 fn from_str() {
1877 use core::str::FromStr;
1882 use std::vec::Vec;
1883
1884 assert_eq!(Name::<Vec<u8>>::from_str(".").unwrap().as_slice(), b"\0");
1885 assert_eq!(
1886 Name::<Vec<u8>>::from_str("www.example.com")
1887 .unwrap()
1888 .as_slice(),
1889 b"\x03www\x07example\x03com\0"
1890 );
1891 assert_eq!(
1892 Name::<Vec<u8>>::from_str("www.example.com.")
1893 .unwrap()
1894 .as_slice(),
1895 b"\x03www\x07example\x03com\0"
1896 );
1897 }
1898
1899 #[test]
1900 fn eq() {
1901 assert_eq!(
1902 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1903 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap()
1904 );
1905 assert_eq!(
1906 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1907 Name::from_slice(b"\x03wWw\x07eXAMple\x03Com\0").unwrap()
1908 );
1909 assert_eq!(
1910 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1911 &RelativeName::from_octets(b"\x03www".as_ref())
1912 .unwrap()
1913 .chain(
1914 RelativeName::from_octets(b"\x07example\x03com".as_ref())
1915 .unwrap()
1916 )
1917 .unwrap()
1918 .chain(Name::root_ref())
1919 .unwrap()
1920 );
1921 assert_eq!(
1922 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1923 &RelativeName::from_octets(b"\x03wWw".as_ref())
1924 .unwrap()
1925 .chain(
1926 RelativeName::from_octets(b"\x07eXAMple\x03coM".as_ref())
1927 .unwrap()
1928 )
1929 .unwrap()
1930 .chain(Name::root_ref())
1931 .unwrap()
1932 );
1933 assert_ne!(
1934 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1935 Name::from_slice(b"\x03ww4\x07example\x03com\0").unwrap()
1936 );
1937 assert_ne!(
1938 Name::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1939 &RelativeName::from_octets(b"\x03www".as_ref())
1940 .unwrap()
1941 .chain(
1942 RelativeName::from_octets(b"\x073xample\x03com".as_ref())
1943 .unwrap()
1944 )
1945 .unwrap()
1946 .chain(Name::root_ref())
1947 .unwrap()
1948 );
1949 }
1950
1951 #[test]
1952 fn cmp() {
1953 use core::cmp::Ordering;
1954
1955 let names = [
1957 Name::from_slice(b"\x07example\0").unwrap(),
1958 Name::from_slice(b"\x01a\x07example\0").unwrap(),
1959 Name::from_slice(b"\x08yljkjljk\x01a\x07example\0").unwrap(),
1960 Name::from_slice(b"\x01Z\x01a\x07example\0").unwrap(),
1961 Name::from_slice(b"\x04zABC\x01a\x07example\0").unwrap(),
1962 Name::from_slice(b"\x01z\x07example\0").unwrap(),
1963 Name::from_slice(b"\x01\x01\x01z\x07example\0").unwrap(),
1964 Name::from_slice(b"\x01*\x01z\x07example\0").unwrap(),
1965 Name::from_slice(b"\x01\xc8\x01z\x07example\0").unwrap(),
1966 ];
1967 for i in 0..names.len() {
1968 for j in 0..names.len() {
1969 let ord = i.cmp(&j);
1970 assert_eq!(names[i].partial_cmp(names[j]), Some(ord));
1971 assert_eq!(names[i].cmp(names[j]), ord);
1972 }
1973 }
1974
1975 let n1 = Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1976 let n2 = Name::from_slice(b"\x03wWw\x07eXAMple\x03Com\0").unwrap();
1977 assert_eq!(n1.partial_cmp(n2), Some(Ordering::Equal));
1978 assert_eq!(n1.cmp(n2), Ordering::Equal);
1979 }
1980
1981 #[test]
1982 #[cfg(feature = "std")]
1983 fn hash() {
1984 use std::collections::hash_map::DefaultHasher;
1985 use std::hash::{Hash, Hasher};
1986
1987 let mut s1 = DefaultHasher::new();
1988 let mut s2 = DefaultHasher::new();
1989 Name::from_slice(b"\x03www\x07example\x03com\0")
1990 .unwrap()
1991 .hash(&mut s1);
1992 Name::from_slice(b"\x03wWw\x07eXAMple\x03Com\0")
1993 .unwrap()
1994 .hash(&mut s2);
1995 assert_eq!(s1.finish(), s2.finish());
1996 }
1997
1998 #[test]
2001 #[cfg(feature = "std")]
2002 fn display() {
2003 use std::string::ToString;
2004
2005 fn cmp(bytes: &[u8], fmt: &str, fmt_with_dot: &str) {
2006 let name = Name::from_octets(bytes).unwrap();
2007 assert_eq!(name.to_string(), fmt);
2008 assert_eq!(format!("{}", name.fmt_with_dot()), fmt_with_dot);
2009 }
2010
2011 cmp(b"\0", ".", ".");
2012 cmp(b"\x03com\0", "com", "com.");
2013 cmp(b"\x07example\x03com\0", "example.com", "example.com.");
2014 }
2015
2016 #[cfg(all(feature = "serde", feature = "std"))]
2017 #[test]
2018 fn ser_de() {
2019 use serde_test::{assert_tokens, Configure, Token};
2020
2021 let name = Name::<Vec<u8>>::from_str("www.example.com.").unwrap();
2022 assert_tokens(
2023 &name.clone().compact(),
2024 &[
2025 Token::NewtypeStruct { name: "Name" },
2026 Token::ByteBuf(b"\x03www\x07example\x03com\0"),
2027 ],
2028 );
2029 assert_tokens(
2030 &name.readable(),
2031 &[
2032 Token::NewtypeStruct { name: "Name" },
2033 Token::Str("www.example.com"),
2034 ],
2035 );
2036 assert_tokens(
2037 &Name::root_vec().readable(),
2038 &[Token::NewtypeStruct { name: "Name" }, Token::Str(".")],
2039 );
2040 }
2041}