1use std::{cmp, fmt, hash, ops, str};
6use bytes::{BufMut, Bytes};
7use ::bits::compose::{Compose, Compress, Compressor};
8use ::bits::parse::{Parse, ParseAll, Parser, ShortBuf};
9use ::master::scan::{CharSource, Scan, Scanner, ScanError, SyntaxError};
10use super::label::{Label, LabelTypeError, SplitLabelError};
11use super::relative::{RelativeDname, DnameIter};
12use super::traits::{ToLabelIter, ToDname};
13use super::uncertain::{UncertainDname, FromStrError};
14
15
16#[derive(Clone)]
35pub struct Dname {
36 bytes: Bytes
37}
38
39impl Dname {
42 pub(super) unsafe fn from_bytes_unchecked(bytes: Bytes) -> Self {
47 Dname { bytes }
48 }
49
50 pub fn root() -> Self {
54 unsafe { Self::from_bytes_unchecked(Bytes::from_static(b"\0")) }
55 }
56
57 pub fn from_bytes(bytes: Bytes) -> Result<Self, DnameBytesError> {
63 if bytes.len() > 255 {
64 return Err(DnameError::LongName.into());
65 }
66 {
67 let mut tmp = bytes.as_ref();
68 loop {
69 let (label, tail) = Label::split_from(tmp)?;
70 if label.is_root() {
71 if tail.is_empty() {
72 break;
73 }
74 else {
75 return Err(DnameBytesError::TrailingData)
76 }
77 }
78 if tail.is_empty() {
79 return Err(DnameBytesError::RelativeName)
80 }
81 tmp = tail;
82 }
83 }
84 Ok(unsafe { Dname::from_bytes_unchecked(bytes) })
85 }
86
87 pub fn from_slice(s: &[u8]) -> Result<Self, DnameBytesError> {
93 Self::from_bytes(s.into())
94 }
95
96 pub fn from_chars<C>(chars: C) -> Result<Self, FromStrError>
112 where C: IntoIterator<Item=char> {
113 UncertainDname::from_chars(chars).map(|res| res.into_absolute())
114 }
115
116 pub fn as_bytes(&self) -> &Bytes {
118 &self.bytes
119 }
120
121 pub fn as_slice(&self) -> &[u8] {
123 self.bytes.as_ref()
124 }
125
126 pub fn into_bytes(self) -> Bytes {
128 self.bytes
129 }
130
131 pub fn into_relative(mut self) -> RelativeDname {
133 let len = self.bytes.len() - 1;
134 self.bytes.truncate(len);
135 unsafe { RelativeDname::from_bytes_unchecked(self.bytes) }
136 }
137}
138
139impl Dname {
145 pub fn is_root(&self) -> bool {
147 self.len() == 1
148 }
149}
150
151
152impl Dname {
155 pub fn iter(&self) -> DnameIter {
157 DnameIter::new(self.bytes.as_ref())
158 }
159
160 pub fn iter_suffixes(&self) -> SuffixIter {
166 SuffixIter::new(self)
167 }
168
169 pub fn label_count(&self) -> usize {
171 self.iter().count()
172 }
173
174 pub fn first(&self) -> &Label {
176 self.iter().next().unwrap()
177 }
178
179 pub fn last(&self) -> &'static Label {
185 Label::root()
186 }
187
188 pub fn starts_with<'a, N: ToLabelIter<'a>>(&'a self, base: &'a N) -> bool {
190 <Self as ToLabelIter>::starts_with(self, base)
191 }
192
193 pub fn ends_with<'a, N: ToLabelIter<'a>>(&'a self, base: &'a N) -> bool {
195 <Self as ToLabelIter>::ends_with(self, base)
196 }
197
198 pub fn is_label_start(&self, mut index: usize) -> bool {
200 if index == 0 {
201 return true
202 }
203 let mut tmp = self.as_slice();
204 while !tmp.is_empty() {
205 let (label, tail) = Label::split_from(tmp).unwrap();
206 let len = label.len() + 1;
207 if index < len || len == 1 { return false
209 }
210 else if index == len {
211 return true
212 }
213 index -= len;
214 tmp = tail;
215 }
216 false
217 }
218
219 fn check_index(&self, index: usize) {
221 if !self.is_label_start(index) {
222 panic!("index not at start of a label");
223 }
224 }
225
226 pub fn slice(&self, begin: usize, end: usize) -> RelativeDname {
243 self.check_index(begin);
244 self.check_index(end);
245 unsafe {
246 RelativeDname::from_bytes_unchecked(self.bytes.slice(begin, end))
247 }
248 }
249
250 pub fn slice_from(&self, begin: usize) -> Self {
257 self.check_index(begin);
258 unsafe {
259 Self::from_bytes_unchecked(self.bytes.slice_from(begin))
260 }
261 }
262
263 pub fn slice_to(&self, end: usize) -> RelativeDname {
271 self.check_index(end);
272 unsafe {
273 RelativeDname::from_bytes_unchecked(self.bytes.slice_to(end))
274 }
275 }
276
277 pub fn split_off(mut self, mid: usize) -> (RelativeDname, Dname) {
291 let left = self.split_to(mid);
292 (left, self)
293 }
294
295 pub fn split_to(&mut self, mid: usize) -> RelativeDname {
305 self.check_index(mid);
306 unsafe {
307 RelativeDname::from_bytes_unchecked(self.bytes.split_to(mid))
308 }
309 }
310
311 pub fn truncate(mut self, len: usize) -> RelativeDname {
321 self.check_index(len);
322 self.bytes.truncate(len);
323 unsafe { RelativeDname::from_bytes_unchecked(self.bytes) }
324 }
325
326 pub fn split_first(&mut self) -> Option<RelativeDname> {
332 if self.len() == 1 {
333 return None
334 }
335 let end = self.iter().next().unwrap().len() + 1;
336 Some(unsafe {
337 RelativeDname::from_bytes_unchecked(self.bytes.split_to(end))
338 })
339 }
340
341 pub fn parent(&mut self) -> bool {
346 self.split_first().is_some()
347 }
348
349 pub fn strip_suffix<N: ToDname>(self, base: &N)
355 -> Result<RelativeDname, Dname> {
356 if self.ends_with(base) {
357 let len = self.compose_len() - base.compose_len();
358 Ok(self.truncate(len))
359 }
360 else {
361 Err(self)
362 }
363 }
364}
365
366
367impl Parse for Dname {
370 type Err = DnameParseError;
371
372 fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
373 let len = name_len(parser)?;
374 Ok(unsafe {
375 Self::from_bytes_unchecked(parser.parse_bytes(len).unwrap())
376 })
377 }
378
379 fn skip(parser: &mut Parser) -> Result<(), Self::Err> {
380 let len = name_len(parser)?;
381 parser.advance(len)?;
382 Ok(())
383 }
384}
385
386fn name_len(parser: &mut Parser) -> Result<usize, DnameParseError> {
387 let len = {
388 let mut tmp = parser.peek_all();
389 loop {
390 if tmp.is_empty() {
391 return Err(ShortBuf.into())
392 }
393 let (label, tail) = Label::split_from(tmp)?;
394 tmp = tail;
395 if label.is_root() {
396 break;
397 }
398 }
399 parser.remaining() - tmp.len()
400 };
401 if len > 255 {
402 Err(DnameError::LongName.into())
403 }
404 else {
405 Ok(len)
406 }
407}
408
409impl ParseAll for Dname {
410 type Err = DnameBytesError;
411
412 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
413 Self::from_bytes(parser.parse_bytes(len)?)
414 }
415}
416
417
418impl Compose for Dname {
419 fn compose_len(&self) -> usize {
420 self.bytes.len()
421 }
422
423 fn compose<B: BufMut>(&self, buf: &mut B) {
424 buf.put_slice(self.as_ref())
425 }
426}
427
428impl Compress for Dname {
429 fn compress(&self, compressor: &mut Compressor) -> Result<(), ShortBuf> {
430 compressor.compress_name(self)
431 }
432}
433
434
435impl str::FromStr for Dname {
438 type Err = FromStrError;
439
440 fn from_str(s: &str) -> Result<Self, Self::Err> {
448 UncertainDname::from_str(s).map(|res| res.into_absolute())
449 }
450}
451
452
453impl<'a> ToLabelIter<'a> for Dname {
456 type LabelIter = DnameIter<'a>;
457
458 fn iter_labels(&'a self) -> Self::LabelIter {
459 self.iter()
460 }
461}
462
463impl ToDname for Dname {
464 fn to_name(&self) -> Dname {
465 self.clone()
466 }
467
468 fn as_flat_slice(&self) -> Option<&[u8]> {
469 Some(self.as_slice())
470 }
471}
472
473
474impl ops::Deref for Dname {
477 type Target = Bytes;
478
479 fn deref(&self) -> &Bytes {
480 self.as_ref()
481 }
482}
483
484impl AsRef<Bytes> for Dname {
485 fn as_ref(&self) -> &Bytes {
486 &self.bytes
487 }
488}
489
490impl AsRef<[u8]> for Dname {
491 fn as_ref(&self) -> &[u8] {
492 self.bytes.as_ref()
493 }
494}
495
496
497impl<'a> IntoIterator for &'a Dname {
500 type Item = &'a Label;
501 type IntoIter = DnameIter<'a>;
502
503 fn into_iter(self) -> Self::IntoIter {
504 self.iter()
505 }
506}
507
508
509impl<N: ToDname> PartialEq<N> for Dname {
512 fn eq(&self, other: &N) -> bool {
513 self.name_eq(other)
514 }
515}
516
517impl Eq for Dname { }
518
519
520impl<N: ToDname> PartialOrd<N> for Dname {
523 fn partial_cmp(&self, other: &N) -> Option<cmp::Ordering> {
530 Some(self.name_cmp(other))
531 }
532}
533
534impl Ord for Dname {
535 fn cmp(&self, other: &Self) -> cmp::Ordering {
542 self.name_cmp(other)
543 }
544}
545
546
547impl hash::Hash for Dname {
550 fn hash<H: hash::Hasher>(&self, state: &mut H) {
551 for item in self.iter() {
552 item.hash(state)
553 }
554 }
555}
556
557
558impl Scan for Dname {
561 fn scan<C: CharSource>(scanner: &mut Scanner<C>)
562 -> Result<Self, ScanError> {
563 let pos = scanner.pos();
564 let name = match UncertainDname::scan(scanner)? {
565 UncertainDname::Relative(name) => name,
566 UncertainDname::Absolute(name) => return Ok(name)
567 };
568 let origin = match *scanner.origin() {
569 Some(ref origin) => origin,
570 None => return Err((SyntaxError::NoOrigin, pos).into())
571 };
572 name.into_builder().append_origin(origin)
573 .map_err(|err| (SyntaxError::from(err), pos).into())
574 }
575}
576
577impl fmt::Display for Dname {
578 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
583 let mut iter = self.iter();
584 write!(f, "{}", iter.next().unwrap())?;
585 for label in iter {
586 if !label.is_root() {
587 write!(f, ".{}", label)?
588 }
589 }
590 Ok(())
591 }
592}
593
594
595impl fmt::Debug for Dname {
598 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
599 write!(f, "Dname({}.)", self)
600 }
601}
602
603
604#[derive(Clone, Debug)]
608pub struct SuffixIter {
609 name: Option<Dname>,
610}
611
612impl SuffixIter {
613 fn new(name: &Dname) -> Self {
615 SuffixIter {
616 name: Some(name.clone())
617 }
618 }
619}
620
621impl Iterator for SuffixIter {
622 type Item = Dname;
623
624 fn next(&mut self) -> Option<Self::Item> {
625 let (res, ok) = match self.name {
626 Some(ref mut name) => (name.clone(), name.parent()),
627 None => return None
628 };
629 if !ok {
630 self.name = None
631 }
632 Some(res)
633 }
634}
635
636
637#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
641pub enum DnameError {
642 #[fail(display="{}", _0)]
643 BadLabel(LabelTypeError),
644
645 #[fail(display="compressed domain name")]
646 CompressedName,
647
648 #[fail(display="long domain name")]
649 LongName,
650}
651
652impl From<LabelTypeError> for DnameError {
653 fn from(err: LabelTypeError) -> DnameError {
654 DnameError::BadLabel(err)
655 }
656}
657
658
659#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
663pub enum DnameParseError {
664 #[fail(display="{}", _0)]
665 BadName(DnameError),
666
667 #[fail(display="unexpected end of buffer")]
668 ShortBuf,
669}
670
671impl<T: Into<DnameError>> From<T> for DnameParseError {
672 fn from(err: T) -> DnameParseError {
673 DnameParseError::BadName(err.into())
674 }
675}
676
677impl From<SplitLabelError> for DnameParseError {
678 fn from(err: SplitLabelError) -> DnameParseError {
679 match err {
680 SplitLabelError::Pointer(_)
681 => DnameParseError::BadName(DnameError::CompressedName),
682 SplitLabelError::BadType(t)
683 => DnameParseError::BadName(DnameError::BadLabel(t)),
684 SplitLabelError::ShortBuf => DnameParseError::ShortBuf,
685 }
686 }
687}
688
689impl From<ShortBuf> for DnameParseError {
690 fn from(_: ShortBuf) -> DnameParseError {
691 DnameParseError::ShortBuf
692 }
693}
694
695
696#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
700pub enum DnameBytesError {
701 #[fail(display="{}", _0)]
702 ParseError(DnameParseError),
703
704 #[fail(display="relative name")]
705 RelativeName,
706
707 #[fail(display="trailing data")]
708 TrailingData,
709}
710
711impl<T: Into<DnameParseError>> From<T> for DnameBytesError {
712 fn from(err: T) -> DnameBytesError {
713 DnameBytesError::ParseError(err.into())
714 }
715}
716
717
718#[cfg(test)]
724pub(crate) mod test {
725 use std::cmp::Ordering;
726 use super::*;
727
728 macro_rules! assert_panic {
729 ( $cond:expr ) => {
730 {
731 let result = ::std::panic::catch_unwind(|| $cond);
732 assert!(result.is_err());
733 }
734 }
735 }
736
737 #[test]
738 fn root() {
739 assert_eq!(Dname::root().as_slice(), b"\0");
740 }
741
742 #[test]
743 fn from_slice() {
744 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0")
746 .unwrap().as_slice(),
747 b"\x03www\x07example\x03com\0");
748
749 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com"),
751 Err(DnameBytesError::RelativeName));
752
753 assert_eq!(Dname::from_slice(b"\x03www\x07exa"),
755 Err(ShortBuf.into()));
756
757 let mut slice = [0u8; 65];
759 slice[0] = 63;
760 assert!(Dname::from_slice(&slice[..]).is_ok());
761 let mut slice = [0u8; 66];
762 slice[0] = 64;
763 assert!(Dname::from_slice(&slice[..]).is_err());
764
765 let mut buf = Vec::new();
767 for _ in 0..25 {
768 buf.extend_from_slice(b"\x09123456789");
769 }
770 assert_eq!(buf.len(), 250);
771 let mut tmp = buf.clone();
772 tmp.extend_from_slice(b"\x03123\0");
773 assert_eq!(Dname::from_slice(&tmp).map(|_| ()), Ok(()));
774 buf.extend_from_slice(b"\x041234\0");
775 assert!(Dname::from_slice(&buf).is_err());
776
777 assert!(Dname::from_slice(b"\x03com\0\x03www\0").is_err());
779
780 assert_eq!(Dname::from_slice(b"\xa2asdasds"),
782 Err(LabelTypeError::Undefined.into()));
783 assert_eq!(Dname::from_slice(b"\x62asdasds"),
784 Err(LabelTypeError::Extended(0x62).into()));
785 assert_eq!(Dname::from_slice(b"\xccasdasds"),
786 Err(DnameError::CompressedName.into()));
787
788 assert_eq!(Dname::from_slice(b""), Err(ShortBuf.into()));
790 }
791
792 #[test]
798 fn into_relative() {
799 assert_eq!(Dname::from_slice(b"\x03www\0").unwrap()
800 .into_relative().as_slice(),
801 b"\x03www");
802 }
803
804 #[test]
805 fn is_root() {
806 assert_eq!(Dname::from_slice(b"\0").unwrap().is_root(), true);
807 assert_eq!(Dname::from_slice(b"\x03www\0").unwrap().is_root(), false);
808 assert_eq!(Dname::root().is_root(), true);
809 }
810
811 pub fn cmp_iter<I>(mut iter: I, labels: &[&[u8]])
812 where
813 I: Iterator,
814 I::Item: AsRef<[u8]>
815 {
816 let mut labels = labels.iter();
817 loop {
818 match (iter.next(), labels.next()) {
819 (Some(left), Some(right)) => assert_eq!(left.as_ref(), *right),
820 (None, None) => break,
821 (_, None) => panic!("extra items in iterator"),
822 (None, _) => panic!("missing items in iterator"),
823 }
824 }
825 }
826
827 #[test]
828 fn iter() {
829 cmp_iter(Dname::root().iter(), &[b""]);
830 cmp_iter(Dname::from_slice(b"\x03www\x07example\x03com\0")
831 .unwrap().iter(),
832 &[b"www", b"example", b"com", b""]);
833 }
834
835 pub fn cmp_iter_back<I>(mut iter: I, labels: &[&[u8]])
836 where
837 I: DoubleEndedIterator,
838 I::Item: AsRef<[u8]>
839 {
840 let mut labels = labels.iter();
841 loop {
842 match (iter.next_back(), labels.next()) {
843 (Some(left), Some(right)) => assert_eq!(left.as_ref(), *right),
844 (None, None) => break,
845 (_, None) => panic!("extra items in iterator"),
846 (None, _) => panic!("missing items in iterator"),
847 }
848 }
849 }
850
851 #[test]
852 fn iter_back() {
853 cmp_iter_back(Dname::root().iter(), &[b""]);
854 cmp_iter_back(Dname::from_slice(b"\x03www\x07example\x03com\0")
855 .unwrap().iter(),
856 &[b"", b"com", b"example", b"www"]);
857 }
858
859 #[test]
860 fn iter_suffixes() {
861 cmp_iter(Dname::root().iter_suffixes(), &[b"\0"]);
862 cmp_iter(Dname::from_slice(b"\x03www\x07example\x03com\0")
863 .unwrap().iter_suffixes(),
864 &[b"\x03www\x07example\x03com\0", b"\x07example\x03com\0",
865 b"\x03com\0", b"\0"]);
866 }
867
868 #[test]
869 fn label_count() {
870 assert_eq!(Dname::root().label_count(), 1);
871 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap()
872 .label_count(),
873 4);
874 }
875
876 #[test]
877 fn first() {
878 assert_eq!(Dname::root().first().as_slice(), b"");
879 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap()
880 .first().as_slice(),
881 b"www");
882 }
883
884 #[test]
887 fn last() {
888 assert_eq!(Dname::root().last().as_slice(), b"");
889 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap()
890 .last().as_slice(),
891 b"");
892 }
893
894 #[test]
895 fn starts_with() {
896 let root = Dname::root();
897 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
898
899 assert!(root.starts_with(&root));
900 assert!(wecr.starts_with(&wecr));
901
902 assert!( root.starts_with(&RelativeDname::empty()));
903 assert!( wecr.starts_with(&RelativeDname::empty()));
904
905 let test = RelativeDname::from_slice(b"\x03www").unwrap();
906 assert!(!root.starts_with(&test));
907 assert!( wecr.starts_with(&test));
908
909 let test = RelativeDname::from_slice(b"\x03www\x07example").unwrap();
910 assert!(!root.starts_with(&test));
911 assert!( wecr.starts_with(&test));
912
913 let test = RelativeDname::from_slice(b"\x03www\x07example\x03com")
914 .unwrap();
915 assert!(!root.starts_with(&test));
916 assert!( wecr.starts_with(&test));
917
918 let test = RelativeDname::from_slice(b"\x07example\x03com").unwrap();
919 assert!(!root.starts_with(&test));
920 assert!(!wecr.starts_with(&test));
921
922 let test = RelativeDname::from_slice(b"\x03www").unwrap()
923 .chain(RelativeDname::from_slice(b"\x07example").unwrap())
924 .unwrap();
925 assert!(!root.starts_with(&test));
926 assert!( wecr.starts_with(&test));
927
928 let test = test.chain(RelativeDname::from_slice(b"\x03com")
929 .unwrap())
930 .unwrap();
931 assert!(!root.starts_with(&test));
932 assert!( wecr.starts_with(&test));
933 }
934
935 #[test]
936 fn ends_with() {
937 let root = Dname::root();
938 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
939
940 for name in wecr.iter_suffixes() {
941 if name.is_root() {
942 assert!(root.ends_with(&name));
943 }
944 else {
945 assert!(!root.ends_with(&name));
946 }
947 assert!(wecr.ends_with(&name));
948 }
949 }
950
951 #[test]
952 fn is_label_start() {
953 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
954
955 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)); }
975
976 #[test]
977 fn slice() {
978 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
979
980 assert_eq!(wecr.slice(0, 4).as_slice(), b"\x03www");
981 assert_eq!(wecr.slice(0, 12).as_slice(), b"\x03www\x07example");
982 assert_eq!(wecr.slice(4, 12).as_slice(), b"\x07example");
983 assert_eq!(wecr.slice(4, 16).as_slice(), b"\x07example\x03com");
984
985 assert_panic!(wecr.slice(0,3));
986 assert_panic!(wecr.slice(1,4));
987 assert_panic!(wecr.slice(0,11));
988 assert_panic!(wecr.slice(1,12));
989 assert_panic!(wecr.slice(0,17));
990 assert_panic!(wecr.slice(4,17));
991 assert_panic!(wecr.slice(0,18));
992 }
993
994 #[test]
995 fn slice_from() {
996 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
997
998 assert_eq!(wecr.slice_from(0).as_slice(),
999 b"\x03www\x07example\x03com\0");
1000 assert_eq!(wecr.slice_from(4).as_slice(), b"\x07example\x03com\0");
1001 assert_eq!(wecr.slice_from(12).as_slice(), b"\x03com\0");
1002 assert_eq!(wecr.slice_from(16).as_slice(), b"\0");
1003
1004 assert_panic!(wecr.slice_from(17));
1005 assert_panic!(wecr.slice_from(18));
1006 }
1007
1008 #[test]
1009 fn slice_to() {
1010 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1011
1012 assert_eq!(wecr.slice_to(0).as_slice(), b"");
1013 assert_eq!(wecr.slice_to(4).as_slice(), b"\x03www");
1014 assert_eq!(wecr.slice_to(12).as_slice(), b"\x03www\x07example");
1015 assert_eq!(wecr.slice_to(16).as_slice(), b"\x03www\x07example\x03com");
1016
1017 assert_panic!(wecr.slice_to(17));
1018 assert_panic!(wecr.slice_to(18));
1019 }
1020
1021 #[test]
1022 fn split_off() {
1023 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1024
1025 let (left, right) = wecr.clone().split_off(0);
1026 assert_eq!(left.as_slice(), b"");
1027 assert_eq!(right.as_slice(), b"\x03www\x07example\x03com\0");
1028
1029 let (left, right) = wecr.clone().split_off(4);
1030 assert_eq!(left.as_slice(), b"\x03www");
1031 assert_eq!(right.as_slice(), b"\x07example\x03com\0");
1032
1033 let (left, right) = wecr.clone().split_off(12);
1034 assert_eq!(left.as_slice(), b"\x03www\x07example");
1035 assert_eq!(right.as_slice(), b"\x03com\0");
1036
1037 let (left, right) = wecr.clone().split_off(16);
1038 assert_eq!(left.as_slice(), b"\x03www\x07example\x03com");
1039 assert_eq!(right.as_slice(), b"\0");
1040
1041 assert_panic!(wecr.clone().split_off(1));
1042 assert_panic!(wecr.clone().split_off(14));
1043 assert_panic!(wecr.clone().split_off(17));
1044 assert_panic!(wecr.clone().split_off(18));
1045 }
1046
1047 #[test]
1048 fn split_to() {
1049 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1050
1051 let mut tmp = wecr.clone();
1052 assert_eq!(tmp.split_to(0).as_slice(), b"");
1053 assert_eq!(tmp.as_slice(), b"\x03www\x07example\x03com\0");
1054
1055 let mut tmp = wecr.clone();
1056 assert_eq!(tmp.split_to(4).as_slice(), b"\x03www");
1057 assert_eq!(tmp.as_slice(), b"\x07example\x03com\0");
1058
1059 let mut tmp = wecr.clone();
1060 assert_eq!(tmp.split_to(12).as_slice(), b"\x03www\x07example");
1061 assert_eq!(tmp.as_slice(), b"\x03com\0");
1062
1063 let mut tmp = wecr.clone();
1064 assert_eq!(tmp.split_to(16).as_slice(), b"\x03www\x07example\x03com");
1065 assert_eq!(tmp.as_slice(), b"\0");
1066
1067 assert_panic!(wecr.clone().split_to(1));
1068 assert_panic!(wecr.clone().split_to(14));
1069 assert_panic!(wecr.clone().split_to(17));
1070 assert_panic!(wecr.clone().split_to(18));
1071 }
1072
1073 #[test]
1074 fn truncate() {
1075 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1076
1077 assert_eq!(wecr.clone().truncate(0).as_slice(),
1078 b"");
1079 assert_eq!(wecr.clone().truncate(4).as_slice(),
1080 b"\x03www");
1081 assert_eq!(wecr.clone().truncate(12).as_slice(),
1082 b"\x03www\x07example");
1083 assert_eq!(wecr.clone().truncate(16).as_slice(),
1084 b"\x03www\x07example\x03com");
1085
1086 assert_panic!(wecr.clone().truncate(1));
1087 assert_panic!(wecr.clone().truncate(14));
1088 assert_panic!(wecr.clone().truncate(17));
1089 assert_panic!(wecr.clone().truncate(18));
1090 }
1091
1092 #[test]
1093 fn split_first() {
1094 let mut wecr = Dname::from_slice(b"\x03www\x07example\x03com\0")
1095 .unwrap();
1096
1097 assert_eq!(wecr.split_first().unwrap().as_slice(), b"\x03www");
1098 assert_eq!(wecr.as_slice(), b"\x07example\x03com\0");
1099 assert_eq!(wecr.split_first().unwrap().as_slice(), b"\x07example");
1100 assert_eq!(wecr.as_slice(), b"\x03com\0");
1101 assert_eq!(wecr.split_first().unwrap().as_slice(), b"\x03com");
1102 assert_eq!(wecr.as_slice(), b"\0");
1103 assert!(wecr.split_first().is_none());
1104 assert_eq!(wecr.as_slice(), b"\0");
1105 assert!(wecr.split_first().is_none());
1106 assert_eq!(wecr.as_slice(), b"\0");
1107 }
1108
1109 #[test]
1110 fn parent() {
1111 let mut wecr = Dname::from_slice(b"\x03www\x07example\x03com\0")
1112 .unwrap();
1113
1114 assert!(wecr.parent());
1115 assert_eq!(wecr.as_slice(), b"\x07example\x03com\0");
1116 assert!(wecr.parent());
1117 assert_eq!(wecr.as_slice(), b"\x03com\0");
1118 assert!(wecr.parent());
1119 assert_eq!(wecr.as_slice(), b"\0");
1120 assert!(!wecr.parent());
1121 assert_eq!(wecr.as_slice(), b"\0");
1122 assert!(!wecr.parent());
1123 assert_eq!(wecr.as_slice(), b"\0");
1124 }
1125
1126 #[test]
1127 fn strip_suffix() {
1128 let wecr = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1129 let ecr = Dname::from_slice(b"\x07example\x03com\0").unwrap();
1130 let cr = Dname::from_slice(b"\x03com\0").unwrap();
1131 let wenr = Dname::from_slice(b"\x03www\x07example\x03net\0").unwrap();
1132 let enr = Dname::from_slice(b"\x07example\x03net\0").unwrap();
1133 let nr = Dname::from_slice(b"\x03net\0").unwrap();
1134
1135 assert_eq!(wecr.clone().strip_suffix(&wecr).unwrap().as_slice(),
1136 b"");
1137 assert_eq!(wecr.clone().strip_suffix(&ecr).unwrap().as_slice(),
1138 b"\x03www");
1139 assert_eq!(wecr.clone().strip_suffix(&cr).unwrap().as_slice(),
1140 b"\x03www\x07example");
1141 assert_eq!(wecr.clone().strip_suffix(&Dname::root())
1142 .unwrap().as_slice(),
1143 b"\x03www\x07example\x03com");
1144
1145 assert_eq!(wecr.clone().strip_suffix(&wenr).unwrap_err().as_slice(),
1146 b"\x03www\x07example\x03com\0");
1147 assert_eq!(wecr.clone().strip_suffix(&enr).unwrap_err().as_slice(),
1148 b"\x03www\x07example\x03com\0");
1149 assert_eq!(wecr.clone().strip_suffix(&nr).unwrap_err().as_slice(),
1150 b"\x03www\x07example\x03com\0");
1151 }
1152
1153 #[test]
1154 fn parse() {
1155 let mut p = Parser::from_static(b"\x03www\x07example\x03com\0af");
1157 assert_eq!(Dname::parse(&mut p).unwrap().as_slice(),
1158 b"\x03www\x07example\x03com\0");
1159 assert_eq!(p.peek_all(), b"af");
1160
1161 let mut p = Parser::from_static(b"\x03www\x07exam");
1163 assert_eq!(Dname::parse(&mut p), Err(ShortBuf.into()));
1164
1165 let mut p = Parser::from_static(b"\x03www\x07example");
1167 assert_eq!(Dname::parse(&mut p), Err(ShortBuf.into()));
1168
1169 let mut p = Parser::from_static(b"\x03com\x03www\x07example\xc0\0");
1171 p.advance(4).unwrap();
1172 assert_eq!(Dname::parse(&mut p),
1173 Err(DnameError::CompressedName.into()));
1174
1175 let mut p = Parser::from_static(b"\x03www\x07example\xbffoo");
1177 assert_eq!(Dname::parse(&mut p),
1178 Err(LabelTypeError::Undefined.into()));
1179
1180 let mut buf = Vec::new();
1182 for _ in 0..50 {
1183 buf.extend_from_slice(b"\x041234");
1184 }
1185 buf.extend_from_slice(b"\x03123\0");
1186 assert_eq!(buf.len(), 255);
1187 let mut p = Parser::from_bytes(buf.into());
1188 assert!(Dname::parse(&mut p).is_ok());
1189 assert_eq!(p.peek_all(), b"");
1190
1191 let mut buf = Vec::new();
1193 for _ in 0..51 {
1194 buf.extend_from_slice(b"\x041234");
1195 }
1196 buf.extend_from_slice(b"\0");
1197 assert_eq!(buf.len(), 256);
1198 let mut p = Parser::from_bytes(buf.into());
1199 assert_eq!(Dname::parse(&mut p),
1200 Err(DnameError::LongName.into()));
1201 }
1202
1203 #[test]
1204 fn parse_all() {
1205 let mut p = Parser::from_static(b"\x03www\x07example\x03com\0af");
1210 assert_eq!(Dname::parse_all(&mut p, 17).unwrap().as_slice(),
1211 b"\x03www\x07example\x03com\0");
1212 assert_eq!(p.peek_all(), b"af");
1213
1214 let mut p = Parser::from_static(b"\0af");
1215 assert_eq!(Dname::parse_all(&mut p, 1).unwrap().as_slice(), b"\0");
1216 assert_eq!(p.peek_all(), b"af");
1217 }
1218
1219 #[test]
1224 fn from_str() {
1225 use std::str::FromStr;
1230
1231 assert_eq!(Dname::from_str("www.example.com").unwrap().as_slice(),
1232 b"\x03www\x07example\x03com\0");
1233 assert_eq!(Dname::from_str("www.example.com.").unwrap().as_slice(),
1234 b"\x03www\x07example\x03com\0");
1235 }
1236
1237 #[test]
1238 fn eq() {
1239 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1240 Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap());
1241 assert_eq!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1242 Dname::from_slice(b"\x03wWw\x07eXAMple\x03Com\0").unwrap());
1243 assert_eq!(
1244 Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1245 RelativeDname::from_slice(b"\x03www").unwrap()
1246 .chain(RelativeDname::from_slice(b"\x07example\x03com")
1247 .unwrap())
1248 .unwrap()
1249 .chain(Dname::root()).unwrap()
1250 );
1251 assert_eq!(
1252 Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1253 RelativeDname::from_slice(b"\x03wWw").unwrap()
1254 .chain(RelativeDname::from_slice(b"\x07eXAMple\x03coM")
1255 .unwrap())
1256 .unwrap()
1257 .chain(Dname::root()).unwrap()
1258 );
1259
1260 assert_ne!(Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1261 Dname::from_slice(b"\x03ww4\x07example\x03com\0").unwrap());
1262 assert_ne!(
1263 Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap(),
1264 RelativeDname::from_slice(b"\x03www").unwrap()
1265 .chain(RelativeDname::from_slice(b"\x073xample\x03com")
1266 .unwrap())
1267 .unwrap()
1268 .chain(Dname::root()).unwrap()
1269 );
1270 }
1271
1272 #[test]
1273 fn cmp() {
1274 let names = [
1276 Dname::from_slice(b"\x07example\0").unwrap(),
1277 Dname::from_slice(b"\x01a\x07example\0").unwrap(),
1278 Dname::from_slice(b"\x08yljkjljk\x01a\x07example\0").unwrap(),
1279 Dname::from_slice(b"\x01Z\x01a\x07example\0").unwrap(),
1280 Dname::from_slice(b"\x04zABC\x01a\x07example\0").unwrap(),
1281 Dname::from_slice(b"\x01z\x07example\0").unwrap(),
1282 Dname::from_slice(b"\x01\x01\x01z\x07example\0").unwrap(),
1283 Dname::from_slice(b"\x01*\x01z\x07example\0").unwrap(),
1284 Dname::from_slice(b"\x01\xc8\x01z\x07example\0").unwrap(),
1285 ];
1286 for i in 0..names.len() {
1287 for j in 0..names.len() {
1288 let ord = if i < j { Ordering::Less }
1289 else if i == j { Ordering::Equal }
1290 else { Ordering::Greater };
1291 assert_eq!(names[i].partial_cmp(&names[j]), Some(ord));
1292 assert_eq!(names[i].cmp(&names[j]), ord);
1293 }
1294 }
1295
1296 let n1 = Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap();
1297 let n2 = Dname::from_slice(b"\x03wWw\x07eXAMple\x03Com\0").unwrap();
1298 assert_eq!(n1.partial_cmp(&n2), Some(Ordering::Equal));
1299 assert_eq!(n1.cmp(&n2), Ordering::Equal);
1300 }
1301
1302 #[test]
1303 fn hash() {
1304 use std::collections::hash_map::DefaultHasher;
1305 use std::hash::{Hash, Hasher};
1306
1307 let mut s1 = DefaultHasher::new();
1308 let mut s2 = DefaultHasher::new();
1309 Dname::from_slice(b"\x03www\x07example\x03com\0").unwrap()
1310 .hash(&mut s1);
1311 Dname::from_slice(b"\x03wWw\x07eXAMple\x03Com\0").unwrap()
1312 .hash(&mut s2);
1313 assert_eq!(s1.finish(), s2.finish());
1314 }
1315
1316 }
1318