domain/base/name/
absolute.rs

1//! Uncompressed, absolute domain names.
2//!
3//! This is a private module. Its public types are re-exported by the parent.
4
5use 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//------------ Name ----------------------------------------------------------
29
30/// An uncompressed, absolute domain name.
31///
32/// The type wraps an octets sequence that contains an absolute domain name in
33/// wire-format encoding. It provides an interface similar to a slice of the
34/// labels of the name, i.e., you can iterate over the labels, split them off,
35/// etc.
36///
37/// You can construct a domain name from a string via the [`FromStr`] trait or
38/// manually via a [`NameBuilder`]. In addition, you can also parse it from
39/// a message. This will, however, require the name to be uncompressed.
40/// Otherwise, you would receive a [`ParsedName`] which can be converted into
41/// [`Name`] via [`ToName::to_name`].
42///
43/// The canonical way to convert a domain name into its presentation format is
44/// using [`to_string`] or by using its [`Display`] implementation (which
45/// performs no allocations).
46///
47/// [`FromStr`]: std::str::FromStr
48/// [`to_string`]: std::string::ToString::to_string
49/// [`ParsedName`]: crate::base::name::ParsedName
50/// [`Display`]: std::fmt::Display
51#[derive(Clone)]
52#[repr(transparent)]
53#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
54pub struct Name<Octs: ?Sized>(Octs);
55
56impl Name<()> {
57    /// Domain names have a maximum length of 255 octets.
58    pub const MAX_LEN: usize = 255;
59}
60
61/// # Creating Values
62///
63impl<Octs> Name<Octs> {
64    /// Creates a domain name from the underlying octets without any check.
65    ///
66    /// Since this will allow to actually construct an incorrectly encoded
67    /// domain name value, the function is unsafe.
68    ///
69    /// # Safety
70    ///
71    /// The octets sequence passed in `octets` must contain a correctly
72    /// encoded absolute domain name. It must be at most 255 octets long.
73    /// It must contain the root label exactly once as its last label.
74    pub const unsafe fn from_octets_unchecked(octets: Octs) -> Self {
75        Self(octets)
76    }
77
78    /// Creates a domain name from an octet sequence.
79    ///
80    /// This will only succeed if `octets` contains a properly encoded
81    /// absolute domain name in wire format. Because the function checks for
82    /// correctness, this will take a wee bit of time.
83    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        // NameBuilder can’t deal with a single dot, so we need to special
101        // case that.
102        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                // Make a root name.
112                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    /// Creates a domain name from a sequence of characters.
130    ///
131    /// The sequence must result in a domain name in representation format.
132    /// That is, its labels should be separated by dots.
133    /// Actual dots, white space and backslashes should be escaped by a
134    /// preceeding backslash, and any byte value that is not a printable
135    /// ASCII character should be encoded by a backslash followed by its
136    /// three digit decimal value.
137    ///
138    /// If Internationalized Domain Names are to be used, the labels already
139    /// need to be in punycode-encoded form.
140    ///
141    /// The name will always be an absolute name. If the last character in the
142    /// sequence is not a dot, the function will quietly add a root label,
143    /// anyway. In most cases, this is likely what you want. If it isn’t,
144    /// though, use [`UncertainName`] instead to be able to check.
145    ///
146    /// [`UncertainName`]: crate::base::name::UncertainName
147    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    /// Reads a name in presentation format from the beginning of a scanner.
162    pub fn scan<S: Scanner<Name = Self>>(
163        scanner: &mut S,
164    ) -> Result<Self, S::Error> {
165        scanner.scan_name()
166    }
167
168    /// Returns a domain name consisting of the root label only.
169    ///
170    /// This function will work for any kind octets sequence that can be
171    /// created from an octets slice. Since this will require providing the
172    /// type parameter in some cases, there are shortcuts methods for specific
173    /// octets types: [`root_ref`], [`root_vec`], and [`root_bytes`].
174    ///
175    /// [`root_ref`]: Name::root_ref
176    /// [`root_vec`]: Name::root_vec
177    /// [`root_bytes`]: Name::root_bytes
178    #[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    /// Creates a domain name for reverse IP address lookup.
187    ///
188    /// The returned name will use the standard suffixes of `in-addr.arpa.`
189    /// for IPv4 addresses and `ip6.arpa.` for IPv6.
190    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    /// Creates a domain name from an octet slice without checking,
225    unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
226        // SAFETY: Name has repr(transparent)
227        mem::transmute(slice)
228    }
229
230    /// Creates a domain name from an octets slice.
231    ///
232    /// Note that the input must be in wire format, as shown below.
233    ///
234    /// # Examples
235    ///
236    /// ```
237    /// use domain::base::name::Name;
238    /// Name::from_slice(b"\x07example\x03com\x00");
239    /// ```
240    ///
241    /// # Errors
242    ///
243    /// This will only succeed if `slice` contains a properly encoded
244    /// absolute domain name.
245    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    /// Creates a domain name for the root label only atop an octets slice.
251    #[must_use]
252    pub fn root_slice() -> &'static Self {
253        unsafe { Self::from_slice_unchecked("\0".as_ref()) }
254    }
255
256    /// Checks whether an octet slice contains a correctly encoded name.
257    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    /// Creates a domain name for the root label only atop a slice reference.
281    #[must_use]
282    pub fn root_ref() -> Self {
283        Self::root()
284    }
285}
286
287#[cfg(feature = "std")]
288impl Name<Vec<u8>> {
289    /// Creates a domain name for the root label only atop a `Vec<u8>`.
290    #[must_use]
291    pub fn root_vec() -> Self {
292        Self::root()
293    }
294
295    /// Creates a domain name atop a `Vec<u8>` from its string representation.
296    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    /// Creates a domain name for the root label only atop a bytes values.
304    pub fn root_bytes() -> Self {
305        Self::root()
306    }
307
308    /// Creates a domain name atop a Bytes from its string representation.
309    pub fn bytes_from_str(s: &str) -> Result<Self, FromStrError> {
310        FromStr::from_str(s)
311    }
312}
313
314/// # Conversions
315///
316impl<Octs: ?Sized> Name<Octs> {
317    /// Returns a reference to the underlying octets sequence.
318    ///
319    /// These octets contain the domain name in wire format.
320    pub fn as_octets(&self) -> &Octs {
321        &self.0
322    }
323
324    /// Converts the domain name into the underlying octets sequence.
325    pub fn into_octets(self) -> Octs
326    where
327        Octs: Sized,
328    {
329        self.0
330    }
331
332    /// Converts the name into a relative name by dropping the root label.
333    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    /// Returns a domain name using a reference to the octets.
343    pub fn for_ref(&self) -> Name<&Octs> {
344        unsafe { Name::from_octets_unchecked(&self.0) }
345    }
346
347    /// Returns a reference to the underlying octets slice.
348    ///
349    /// The slice will contain the domain name in wire format.
350    pub fn as_slice(&self) -> &[u8]
351    where
352        Octs: AsRef<[u8]>,
353    {
354        self.0.as_ref()
355    }
356
357    /// Returns a domain name for the octets slice of the content.
358    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    /// Converts the domain name into its canonical form.
366    ///
367    /// This will convert all octets that are upper case ASCII characters
368    /// into their lower case equivalent.
369    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
377/// # Properties
378///
379impl<Octs: AsRef<[u8]> + ?Sized> Name<Octs> {
380    /// Returns whether the name is the root label only.
381    pub fn is_root(&self) -> bool {
382        self.0.as_ref().len() == 1
383    }
384
385    /// Returns the length of the domain name.
386    #[allow(clippy::len_without_is_empty)] // never empty ...
387    pub fn len(&self) -> usize {
388        self.0.as_ref().len()
389    }
390
391    /// Returns an object that displays the name with a final dot.
392    ///
393    /// The name itself displays without a final dot unless the name is the
394    /// root label only. Because this means you can’t just unconditionally
395    /// add a dot after the name, this method can be used to display the name
396    /// always ending in a single dot.
397    pub fn fmt_with_dot(&self) -> impl fmt::Display + '_ {
398        ToName::fmt_with_dot(self)
399    }
400}
401
402/// # Working with Labels
403///
404impl<Octs: AsRef<[u8]> + ?Sized> Name<Octs> {
405    /// Returns an iterator over the labels of the domain name.
406    pub fn iter(&self) -> NameIter {
407        NameIter::new(self.0.as_ref())
408    }
409
410    /// Returns an iterator over the suffixes of the name.
411    ///
412    /// The returned iterator starts with the full name and then for each
413    /// additional step returns a name with the left-most label stripped off
414    /// until it reaches the root label.
415    pub fn iter_suffixes(&self) -> SuffixIter<'_, Octs> {
416        SuffixIter::new(self)
417    }
418
419    /// Returns the number of labels in the domain name.
420    pub fn label_count(&self) -> usize {
421        self.iter().count()
422    }
423
424    /// Returns a reference to the first label.
425    pub fn first(&self) -> &Label {
426        self.iter().next().unwrap()
427    }
428
429    /// Returns a reference to the last label.
430    ///
431    /// Because the last label in an absolute name is always the root label,
432    /// this method can return a static reference. It is also a wee bit silly,
433    /// but here for completeness.
434    pub fn last(&self) -> &'static Label {
435        Label::root()
436    }
437
438    /// Determines whether `base` is a prefix of `self`.
439    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    /// Determines whether `base` is a suffix of `self`.
447    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    /// Returns whether an index points to the first byte of a non-root label.
455    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                // length 1: root label.
465                return false;
466            } else if index == len {
467                return true;
468            }
469            index -= len;
470            tmp = tail;
471        }
472        false
473    }
474
475    /// Like `is_label_start` but panics if it isn’t.
476    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    /// Checks that a range starts and ends at label bounds.
483    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    /// Returns the part of the name indicated by start and end positions.
502    ///
503    /// The returned name will start at position `begin` and end right before
504    /// position `end`. Both positions are given as indexes into the
505    /// underlying octets sequence and must point to the begining of a label.
506    ///
507    /// The method returns a reference to an unsized relative domain name and
508    /// is thus best suited for temporary referencing. If you want to keep the
509    /// part of the name around, [`range`] is likely a better choice.
510    ///
511    /// # Panics
512    ///
513    /// The method panics if either position is not the start of a label or is
514    /// out of bounds.
515    ///
516    /// Because the returned domain name is relative, the method will also
517    /// panic if the end is equal to the length of the name. If you want to
518    /// slice the entire end of the name including the final root label, you
519    /// can use [`slice_from`] instead.
520    ///
521    /// [`range`]: Name::range
522    /// [`slice_from`]: Name::slice_from
523    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    /// Returns the part of the name starting at the given position.
534    ///
535    /// The returned name will start at the given postion and cover the
536    /// remainder of the name. The position `begin` is provided as an index
537    /// into the underlying octets sequence and must point to the beginning
538    /// of a label.
539    ///
540    /// The method returns a reference to an unsized domain name and
541    /// is thus best suited for temporary referencing. If you want to keep the
542    /// part of the name around, [`range_from`] is likely a better choice.
543    ///
544    /// # Panics
545    ///
546    /// The method panics if `begin` isn’t the index of the beginning of a
547    /// label or is out of bounds.
548    ///
549    /// [`range_from`]: Name::range_from
550    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    /// Returns the part of the name indicated by start and end positions.
556    ///
557    /// The returned name will start at position `begin` and end right before
558    /// position `end`. Both positions are given as indexes into the
559    /// underlying octets sequence and must point to the begining of a label.
560    ///
561    /// # Panics
562    ///
563    /// The method panics if either position is not the start of a label or
564    /// is out of bounds.
565    ///
566    /// Because the returned domain name is relative, the method will also
567    /// panic if the end is equal to the length of the name. If you
568    /// want to slice the entire end of the name including the final root
569    /// label, you can use [`range_from`] instead.
570    ///
571    /// [`range_from`]: Name::range_from
572    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    /// Returns the part of the name starting at the given position.
584    ///
585    /// The returned name will start at the given postion and cover the
586    /// remainder of the name. The position `begin` is provided as an index
587    /// into the underlying octets sequence and must point to the beginning
588    /// of a label.
589    ///
590    /// # Panics
591    ///
592    /// The method panics if `begin` isn’t the index of the beginning of a
593    /// label or is out of bounds.
594    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    /// Returns the part of the name starting at a position without checking.
606    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    /// Splits the name into two at the given position.
619    ///
620    /// Returns a pair of the left and right part of the split name.
621    ///
622    /// # Panics
623    ///
624    /// The method will panic if `mid` is not the index of the beginning of
625    /// a label or if it is out of bounds.
626    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    /// Truncates the name before `len`.
643    ///
644    /// Because truncating converts the name into a relative name, the method
645    /// consumes self.
646    ///
647    /// # Panics
648    ///
649    /// The method will panic if `len` is not the index of a new label or if
650    /// it is out of bounds.
651    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    /// Splits off the first label.
661    ///
662    /// If this name is longer than just the root label, returns a pair
663    /// of that label and the remaining name. If the name is only the root
664    /// label, returns `None`.
665    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    /// Returns the parent of the current name.
677    ///
678    /// If the name consists of the root label only, returns `None`.
679    pub fn parent(&self) -> Option<Name<Octs::Range<'_>>>
680    where
681        Octs: Octets,
682    {
683        self.split_first().map(|(_, parent)| parent)
684    }
685
686    /// Strips the suffix `base` from the domain name.
687    ///
688    /// If `base` is indeed a suffix, returns a relative domain name with the
689    /// remainder of the name. Otherwise, returns an error with an unmodified
690    /// `self`.
691    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    /// Reads a name in wire format from the beginning of a parser.
709    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    /// Peeks at a parser and returns the length of a name at its beginning.
717    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
742//--- AsRef
743
744impl<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
756//--- OctetsFrom
757
758impl<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
770//--- FromStr
771
772impl<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    /// Parses a string into an absolute domain name.
783    ///
784    /// The name needs to be formatted in representation format, i.e., as a
785    /// sequence of labels separated by dots. If Internationalized Domain
786    /// Name (IDN) labels are to be used, these need to be given in punycode
787    /// encoded form.
788    ///
789    /// The implementation assumes that the string refers to an absolute name
790    /// whether it ends in a dot or not. If you need to be able to distinguish
791    /// between those two cases, you can use [`UncertainDname`] instead.
792    ///
793    /// [`UncertainDname`]: struct.UncertainDname.html
794    fn from_str(s: &str) -> Result<Self, Self::Err> {
795        Self::from_chars(s.chars())
796    }
797}
798
799//--- FlattenInto
800
801impl<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
813//--- PartialEq, and Eq
814
815impl<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
827//--- PartialOrd, Ord, and CanonicalOrd
828
829impl<Octs, N> PartialOrd<N> for Name<Octs>
830where
831    Octs: AsRef<[u8]> + ?Sized,
832    N: ToName + ?Sized,
833{
834    /// Returns the ordering between `self` and `other`.
835    ///
836    /// Domain name order is determined according to the ‘canonical DNS
837    /// name order’ as defined in [section 6.1 of RFC 4034][RFC4034-6.1].
838    ///
839    /// [RFC4034-6.1]: https://tools.ietf.org/html/rfc4034#section-6.1
840    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    /// Returns the ordering between `self` and `other`.
847    ///
848    /// Domain name order is determined according to the ‘canonical DNS
849    /// name order’ as defined in [section 6.1 of RFC 4034][RFC4034-6.1].
850    ///
851    /// [RFC4034-6.1]: https://tools.ietf.org/html/rfc4034#section-6.1
852    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
867//--- Hash
868
869impl<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
877//--- ToLabelIter and ToName
878
879impl<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
903//--- IntoIterator
904
905impl<'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
917//--- Display
918
919impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for Name<Octs> {
920    /// Formats the domain name.
921    ///
922    /// This will produce the domain name in ‘common display format’ without
923    /// the trailing dot with the exception of a root name which will be just
924    /// a dot.
925    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
941//--- Debug
942
943impl<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
949//--- AsRef and Borrow
950
951impl<Octs: AsRef<[u8]>> AsRef<Name<[u8]>> for Name<Octs> {
952    fn as_ref(&self) -> &Name<[u8]> {
953        self.for_slice()
954    }
955}
956
957/// Borrow a domain name.
958///
959/// Containers holding an owned `Name<_>` may be queried with name over a
960/// slice. This `Borrow<_>` impl supports user code querying containers with
961/// compatible-but-different types like the following example:
962///
963/// ```
964/// use std::collections::HashMap;
965///
966/// use domain::base::Name;
967///
968/// fn get_description(
969///     hash: &HashMap<Name<Vec<u8>>, String>
970/// ) -> Option<&str> {
971///     let lookup_name: &Name<[u8]> =
972///         Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
973///     hash.get(lookup_name).map(|x| x.as_ref())
974/// }
975/// ```
976impl<Octs: AsRef<[u8]>> borrow::Borrow<Name<[u8]>> for Name<Octs> {
977    fn borrow(&self) -> &Name<[u8]> {
978        self.for_slice()
979    }
980}
981
982//--- Serialize and Deserialize
983
984#[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//------------ SuffixIter ----------------------------------------------------
1100
1101/// An iterator over ever shorter suffixes of a domain name.
1102#[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    /// Creates a new iterator cloning `name`.
1110    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//============ Error Types ===================================================
1135
1136//------------ NameError -----------------------------------------------------
1137
1138/// A domain name wasn’t encoded correctly.
1139#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1140pub struct NameError(DnameErrorEnum);
1141
1142#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1143enum DnameErrorEnum {
1144    /// The encoding contained an unknown or disallowed label type.
1145    BadLabel(LabelTypeError),
1146
1147    /// The encoding contained a compression pointer.
1148    CompressedName,
1149
1150    /// The name was longer than 255 octets.
1151    LongName,
1152
1153    /// The name did not end with the root label.
1154    RelativeName,
1155
1156    /// There was more data after the root label was encountered.
1157    TrailingData,
1158
1159    /// The input ended in the middle of a label.
1160    ShortInput,
1161}
1162
1163//--- From
1164
1165impl 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
1203//--- Display and Error
1204
1205impl 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//============ Testing =======================================================
1224//
1225// Some of the helper functions herein are resused by the tests of other
1226// sub-modules of ::bits::name. Hence the `pub(crate)` designation.
1227
1228#[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        // a simple good name
1286        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        // relative name
1294        assert_eq!(
1295            Name::from_slice(b"\x03www\x07example\x03com"),
1296            Err(NameError(DnameErrorEnum::RelativeName))
1297        );
1298
1299        // bytes shorter than what label length says.
1300        assert_eq!(
1301            Name::from_slice(b"\x03www\x07exa"),
1302            Err(NameError(DnameErrorEnum::ShortInput))
1303        );
1304
1305        // label 63 long ok, 64 bad.
1306        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        // name 255 long ok, 256 bad.
1314        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        // trailing data
1326        assert!(Name::from_slice(b"\x03com\0\x03www\0").is_err());
1327
1328        // bad label heads: compressed, other types.
1329        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        // empty input
1343        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    // `Name::from_chars` is covered in the `FromStr` test.
1372    //
1373    // No tests for the simple conversion methods because, well, simple.
1374
1375    #[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)); // \x03
1579        assert!(!wecr.is_label_start(1)); // w
1580        assert!(!wecr.is_label_start(2)); // w
1581        assert!(!wecr.is_label_start(3)); // w
1582        assert!(wecr.is_label_start(4)); // \x07
1583        assert!(!wecr.is_label_start(5)); // e
1584        assert!(!wecr.is_label_start(6)); // x
1585        assert!(!wecr.is_label_start(7)); // a
1586        assert!(!wecr.is_label_start(8)); // m
1587        assert!(!wecr.is_label_start(9)); // p
1588        assert!(!wecr.is_label_start(10)); // l
1589        assert!(!wecr.is_label_start(11)); // e
1590        assert!(wecr.is_label_start(12)); // \x03
1591        assert!(!wecr.is_label_start(13)); // c
1592        assert!(!wecr.is_label_start(14)); // o
1593        assert!(!wecr.is_label_start(15)); // m
1594        assert!(wecr.is_label_start(16)); // \0
1595        assert!(!wecr.is_label_start(17)); //
1596        assert!(!wecr.is_label_start(18)); //
1597    }
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        // Parse a correctly formatted name.
1805        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        // Short buffer in middle of label.
1813        let mut p = Parser::from_static(b"\x03www\x07exam");
1814        assert_eq!(Name::parse(&mut p), Err(ParseError::ShortInput));
1815
1816        // Short buffer at end of label.
1817        let mut p = Parser::from_static(b"\x03www\x07example");
1818        assert_eq!(Name::parse(&mut p), Err(ParseError::ShortInput));
1819
1820        // Compressed name.
1821        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        // Bad label header.
1829        let mut p = Parser::from_static(b"\x03www\x07example\xbffoo");
1830        assert!(Name::parse(&mut p).is_err());
1831
1832        // Long name: 255 bytes is fine.
1833        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        // Long name: 256 bytes are bad.
1844        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    // I don’t think we need tests for `Compose::compose` since it only
1858    // copies the underlying bytes.
1859
1860    #[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        // Another simple test. `NameBuilder` does all the heavy lifting,
1878        // so we don’t need to test all the escape sequence shenanigans here.
1879        // Just check that we’ll always get a name, final dot or not, unless
1880        // the string is empty.
1881        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        // The following is taken from section 6.1 of RFC 4034.
1956        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    // Scan skipped for now.
1999
2000    #[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}