1use std::{
13 borrow::Cow,
14 cmp::max,
15 time::{Duration, SystemTime},
16};
17
18use bytes::{Buf, BufMut, Bytes, BytesMut};
19use derive_more::{AsMut, AsRef, Display, From, Into};
20use ndn_tlv::{NonNegativeInteger, Tlv, TlvDecode, TlvEncode, VarNum};
21use url::Url;
22
23use crate::error::{NdnError, Result};
24
25trait FromUriPart: Sized {
26 fn from_uri_part(s: &[u8]) -> Option<Self>;
27}
28
29trait ToUriPart {
30 fn to_uri_part(&self) -> String;
31}
32
33#[derive(Debug, Tlv, PartialEq, Eq, Clone, Hash, From, Into, AsRef, AsMut)]
36#[tlv(8)]
37pub struct GenericNameComponent {
38 pub name: Bytes,
40}
41
42impl GenericNameComponent {
43 pub fn new(name: Bytes) -> Self {
45 Self { name }
46 }
47}
48
49impl FromUriPart for GenericNameComponent {
50 fn from_uri_part(s: &[u8]) -> Option<Self> {
51 let name = if s.starts_with(b"8=") {
52 Bytes::copy_from_slice(&s[2..])
53 } else {
54 Bytes::copy_from_slice(s)
55 };
56 Some(Self { name })
57 }
58}
59
60impl ToUriPart for GenericNameComponent {
61 fn to_uri_part(&self) -> String {
62 let name = if self.name.iter().all(|x| *x == b'.') {
63 Bytes::from_iter(b"...".iter().chain(self.name.iter()).map(|x| *x))
64 } else {
65 self.name.clone()
66 };
67 urlencoding::encode_binary(&name).into_owned()
68 }
69}
70
71#[derive(Debug, Tlv, PartialEq, Eq, Clone, Hash, From, Into, AsRef, AsMut)]
74#[tlv(32)]
75pub struct KeywordNameComponent {
76 pub name: Bytes,
78}
79
80impl KeywordNameComponent {
81 pub fn new(name: Bytes) -> Self {
83 Self { name }
84 }
85}
86
87impl FromUriPart for KeywordNameComponent {
88 fn from_uri_part(s: &[u8]) -> Option<Self> {
89 let name = if s.starts_with(b"32=") {
90 Bytes::copy_from_slice(&s[3..])
91 } else {
92 return None;
93 };
94 Some(Self { name })
95 }
96}
97
98impl ToUriPart for KeywordNameComponent {
99 fn to_uri_part(&self) -> String {
100 format!("32={}", urlencoding::encode_binary(&self.name))
101 }
102}
103
104#[derive(
107 Debug,
108 Tlv,
109 PartialEq,
110 Eq,
111 Clone,
112 Hash,
113 Default,
114 PartialOrd,
115 Ord,
116 From,
117 Into,
118 AsRef,
119 AsMut,
120 Display,
121)]
122#[tlv(50)]
123pub struct SegmentNameComponent {
124 pub segment_number: NonNegativeInteger,
126}
127
128impl SegmentNameComponent {
129 pub fn new(segment_number: NonNegativeInteger) -> Self {
131 Self { segment_number }
132 }
133}
134
135impl From<u64> for SegmentNameComponent {
136 fn from(value: u64) -> Self {
137 Self::new(NonNegativeInteger::new(value))
138 }
139}
140
141impl From<usize> for SegmentNameComponent {
142 fn from(value: usize) -> Self {
143 Self::new(NonNegativeInteger::new(value as u64))
144 }
145}
146
147impl FromUriPart for SegmentNameComponent {
148 fn from_uri_part(s: &[u8]) -> Option<Self> {
149 let name = if s.starts_with(b"50=") {
150 let mut buf = [0; std::mem::size_of::<u64>()];
151 let slice = &s[3..];
152
153 let start_idx = max(0, buf.len() - slice.len());
154 for i in start_idx..buf.len() {
155 buf[i] = slice[i - start_idx];
156 }
157
158 NonNegativeInteger::new(u64::from_be_bytes(buf))
159 } else if s.starts_with(b"seg=") {
160 let number = std::str::from_utf8(&s[4..]).ok()?.parse::<u64>().ok()?;
161 NonNegativeInteger::new(number)
162 } else {
163 return None;
164 };
165 Some(Self {
166 segment_number: name,
167 })
168 }
169}
170
171impl ToUriPart for SegmentNameComponent {
172 fn to_uri_part(&self) -> String {
173 format!("seg={}", self.segment_number)
174 }
175}
176
177#[derive(
180 Debug,
181 Tlv,
182 PartialEq,
183 Eq,
184 Clone,
185 Hash,
186 PartialOrd,
187 Ord,
188 Default,
189 From,
190 Into,
191 AsRef,
192 AsMut,
193 Display,
194)]
195#[tlv(52)]
196pub struct ByteOffsetNameComponent {
197 pub offset: NonNegativeInteger,
199}
200
201impl ByteOffsetNameComponent {
202 pub fn new(offset: NonNegativeInteger) -> Self {
204 Self { offset }
205 }
206}
207
208impl From<u64> for ByteOffsetNameComponent {
209 fn from(value: u64) -> Self {
210 Self::new(NonNegativeInteger::new(value))
211 }
212}
213
214impl From<usize> for ByteOffsetNameComponent {
215 fn from(value: usize) -> Self {
216 Self::new(NonNegativeInteger::new(value as u64))
217 }
218}
219
220impl FromUriPart for ByteOffsetNameComponent {
221 fn from_uri_part(s: &[u8]) -> Option<Self> {
222 let name = if s.starts_with(b"52=") {
223 let mut buf = [0; std::mem::size_of::<u64>()];
224 let slice = &s[3..];
225
226 let start_idx = max(0, buf.len() - slice.len());
227 for i in start_idx..buf.len() {
228 buf[i] = slice[i - start_idx];
229 }
230
231 NonNegativeInteger::new(u64::from_be_bytes(buf))
232 } else if s.starts_with(b"off=") {
233 let number = std::str::from_utf8(&s[4..]).ok()?.parse::<u64>().ok()?;
234 NonNegativeInteger::new(number)
235 } else {
236 return None;
237 };
238 Some(Self { offset: name })
239 }
240}
241
242impl ToUriPart for ByteOffsetNameComponent {
243 fn to_uri_part(&self) -> String {
244 format!("off={}", self.offset)
245 }
246}
247
248#[derive(
251 Debug,
252 Tlv,
253 PartialEq,
254 Eq,
255 Clone,
256 Hash,
257 PartialOrd,
258 Ord,
259 Default,
260 From,
261 Into,
262 AsRef,
263 AsMut,
264 Display,
265)]
266#[tlv(54)]
267pub struct VersionNameComponent {
268 pub version: NonNegativeInteger,
270}
271
272impl VersionNameComponent {
273 pub fn new(version: NonNegativeInteger) -> Self {
275 Self { version }
276 }
277}
278
279impl From<u64> for VersionNameComponent {
280 fn from(value: u64) -> Self {
281 Self::new(NonNegativeInteger::new(value))
282 }
283}
284
285impl From<usize> for VersionNameComponent {
286 fn from(value: usize) -> Self {
287 Self::new(NonNegativeInteger::new(value as u64))
288 }
289}
290
291impl FromUriPart for VersionNameComponent {
292 fn from_uri_part(s: &[u8]) -> Option<Self> {
293 let name = if s.starts_with(b"54=") {
294 let mut buf = [0; std::mem::size_of::<u64>()];
295 let slice = &s[3..];
296
297 let start_idx = max(0, buf.len() - slice.len());
298 for i in start_idx..buf.len() {
299 buf[i] = slice[i - start_idx];
300 }
301
302 NonNegativeInteger::new(u64::from_be_bytes(buf))
303 } else if s.starts_with(b"v=") {
304 let number = std::str::from_utf8(&s[2..]).ok()?.parse::<u64>().ok()?;
305 NonNegativeInteger::new(number)
306 } else {
307 return None;
308 };
309 Some(Self { version: name })
310 }
311}
312
313impl ToUriPart for VersionNameComponent {
314 fn to_uri_part(&self) -> String {
315 format!("v={}", self.version)
316 }
317}
318
319#[derive(
322 Debug, Tlv, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, From, Into, AsRef, AsMut, Display,
323)]
324#[tlv(56)]
325pub struct TimestampNameComponent {
326 pub time: NonNegativeInteger,
328}
329
330impl TimestampNameComponent {
331 pub fn new(time: NonNegativeInteger) -> Self {
333 Self { time }
334 }
335
336 pub fn now() -> Self {
338 Self::new(NonNegativeInteger::new(
339 SystemTime::now()
340 .duration_since(SystemTime::UNIX_EPOCH)
341 .unwrap_or(Duration::ZERO)
342 .as_millis() as u64,
343 ))
344 }
345}
346
347impl Default for TimestampNameComponent {
348 fn default() -> Self {
349 Self::now()
350 }
351}
352
353impl From<u64> for TimestampNameComponent {
354 fn from(value: u64) -> Self {
355 Self::new(NonNegativeInteger::new(value))
356 }
357}
358
359impl From<usize> for TimestampNameComponent {
360 fn from(value: usize) -> Self {
361 Self::new(NonNegativeInteger::new(value as u64))
362 }
363}
364
365impl FromUriPart for TimestampNameComponent {
366 fn from_uri_part(s: &[u8]) -> Option<Self> {
367 let name = if s.starts_with(b"56=") {
368 let mut buf = [0; std::mem::size_of::<u64>()];
369 let slice = &s[3..];
370
371 let start_idx = max(0, buf.len() - slice.len());
372 for i in start_idx..buf.len() {
373 buf[i] = slice[i - start_idx];
374 }
375
376 NonNegativeInteger::new(u64::from_be_bytes(buf))
377 } else if s.starts_with(b"t=") {
378 let number = std::str::from_utf8(&s[2..]).ok()?.parse::<u64>().ok()?;
379 NonNegativeInteger::new(number)
380 } else {
381 return None;
382 };
383 Some(Self { time: name })
384 }
385}
386
387impl ToUriPart for TimestampNameComponent {
388 fn to_uri_part(&self) -> String {
389 format!("t={}", self.time)
390 }
391}
392
393#[derive(
396 Debug,
397 Tlv,
398 PartialEq,
399 Eq,
400 Clone,
401 Hash,
402 PartialOrd,
403 Ord,
404 Default,
405 From,
406 Into,
407 AsRef,
408 AsMut,
409 Display,
410)]
411#[tlv(58)]
412pub struct SequenceNumNameComponent {
413 pub sequence_number: NonNegativeInteger,
415}
416
417impl SequenceNumNameComponent {
418 pub fn new(sequence_number: NonNegativeInteger) -> Self {
420 Self { sequence_number }
421 }
422}
423
424impl From<u64> for SequenceNumNameComponent {
425 fn from(value: u64) -> Self {
426 Self::new(NonNegativeInteger::new(value))
427 }
428}
429
430impl From<usize> for SequenceNumNameComponent {
431 fn from(value: usize) -> Self {
432 Self::new(NonNegativeInteger::new(value as u64))
433 }
434}
435
436impl FromUriPart for SequenceNumNameComponent {
437 fn from_uri_part(s: &[u8]) -> Option<Self> {
438 let name = if s.starts_with(b"58=") {
439 let mut buf = [0; std::mem::size_of::<u64>()];
440 let slice = &s[3..];
441
442 let start_idx = max(0, buf.len() - slice.len());
443 for i in start_idx..buf.len() {
444 buf[i] = slice[i - start_idx];
445 }
446
447 NonNegativeInteger::new(u64::from_be_bytes(buf))
448 } else if s.starts_with(b"seq=") {
449 let number = std::str::from_utf8(&s[4..]).ok()?.parse::<u64>().ok()?;
450 NonNegativeInteger::new(number)
451 } else {
452 return None;
453 };
454 Some(Self {
455 sequence_number: name,
456 })
457 }
458}
459
460impl ToUriPart for SequenceNumNameComponent {
461 fn to_uri_part(&self) -> String {
462 format!("seq={}", self.sequence_number)
463 }
464}
465
466#[derive(Debug, Tlv, PartialEq, Eq, Clone, Hash, From, Into, AsRef, AsMut)]
470#[tlv(1)]
471pub struct ImplicitSha256DigestComponent {
472 pub(crate) name: [u8; 32],
473}
474
475impl FromUriPart for ImplicitSha256DigestComponent {
476 fn from_uri_part(s: &[u8]) -> Option<Self> {
477 let mut name = [0; 32];
478 if s.starts_with(b"sha256digest=") {
479 hex::decode_to_slice(&s["sha256digest=".len()..], &mut name).ok()?;
480 } else {
481 assert!(s.starts_with(b"1="));
482 name.clone_from_slice(&s[2..]);
483 }
484 Some(Self { name })
485 }
486}
487
488impl ToUriPart for ImplicitSha256DigestComponent {
489 fn to_uri_part(&self) -> String {
490 format!("sha256digest={}", hex::encode(&self.name))
491 }
492}
493
494impl std::fmt::Display for ImplicitSha256DigestComponent {
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496 if f.alternate() {
497 write!(f, "{}", hex::encode_upper(self.name))
498 } else {
499 write!(f, "{}", hex::encode(self.name))
500 }
501 }
502}
503
504#[derive(Debug, Tlv, PartialEq, Eq, Clone, Hash, From, Into, AsRef, AsMut)]
509#[tlv(2)]
510pub struct ParametersSha256DigestComponent {
511 pub(crate) name: [u8; 32],
512}
513
514impl FromUriPart for ParametersSha256DigestComponent {
515 fn from_uri_part(s: &[u8]) -> Option<Self> {
516 let mut name = [0; 32];
517 if s.starts_with(b"params-sha256=") {
518 hex::decode_to_slice(&s["params-sha256=".len()..], &mut name).ok()?;
519 } else {
520 assert!(s.starts_with(b"2="));
521 name.clone_from_slice(&s[2..]);
522 }
523 Some(Self { name })
524 }
525}
526
527impl ToUriPart for ParametersSha256DigestComponent {
528 fn to_uri_part(&self) -> String {
529 format!("params-sha256={}", hex::encode(&self.name))
530 }
531}
532
533impl std::fmt::Display for ParametersSha256DigestComponent {
534 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
535 if f.alternate() {
536 write!(f, "{}", hex::encode_upper(self.name))
537 } else {
538 write!(f, "{}", hex::encode(self.name))
539 }
540 }
541}
542
543#[derive(Debug, PartialEq, Eq, Clone, Hash)]
546pub struct OtherNameComponent {
547 pub typ: VarNum,
549 pub length: VarNum,
551 pub data: Bytes,
553}
554
555impl FromUriPart for OtherNameComponent {
556 fn from_uri_part(segment: &[u8]) -> Option<OtherNameComponent> {
557 let (start, end) = segment.split_at(segment.partition_point(|x| *x == b'='));
558 let typ = std::str::from_utf8(&start[..start.len() - 1]).ok()?;
559 let length = end.len();
560
561 let mut buf = BytesMut::with_capacity(length);
562 buf.put(&end[..]);
563
564 Some(OtherNameComponent {
565 typ: VarNum::from(typ.parse::<u64>().ok()?),
566 length: VarNum::from(length),
567 data: buf.freeze(),
568 })
569 }
570}
571
572impl TlvEncode for OtherNameComponent {
573 fn encode(&self) -> Bytes {
574 let mut buf = BytesMut::with_capacity(self.size());
575 buf.put(self.typ.encode());
576 buf.put(self.length.encode());
577 buf.put(self.data.encode());
578 buf.freeze()
579 }
580
581 fn size(&self) -> usize {
582 self.typ.size() + self.length.size() + self.data.len()
583 }
584}
585
586impl TlvDecode for OtherNameComponent {
587 fn decode(bytes: &mut Bytes) -> ndn_tlv::Result<Self> {
588 let typ = VarNum::decode(bytes)?;
589 let length = VarNum::decode(bytes)?;
590
591 if bytes.remaining() < length.into() {
592 return Err(ndn_tlv::TlvError::UnexpectedEndOfStream);
593 }
594
595 let mut buf = BytesMut::with_capacity(length.into());
596 bytes.copy_to_slice(&mut buf);
597 Ok(Self {
598 typ,
599 length,
600 data: buf.freeze(),
601 })
602 }
603}
604
605impl ToUriPart for OtherNameComponent {
606 fn to_uri_part(&self) -> String {
607 format!(
608 "{}={}",
609 self.typ.value(),
610 urlencoding::encode_binary(&self.data)
611 )
612 }
613}
614
615#[derive(Debug, Tlv, PartialEq, Eq, Clone, From, Hash)]
626pub enum NameComponent {
627 GenericNameComponent(GenericNameComponent),
629 ImplicitSha256DigestComponent(ImplicitSha256DigestComponent),
631 ParametersSha256DigestComponent(ParametersSha256DigestComponent),
634 KeywordNameComponent(KeywordNameComponent),
636 SegmentNameComponent(SegmentNameComponent),
638 ByteOffsetNameComponent(ByteOffsetNameComponent),
640 VersionNameComponent(VersionNameComponent),
642 TimestampNameComponent(TimestampNameComponent),
644 SequenceNumNameComponent(SequenceNumNameComponent),
646 #[tlv(default)]
648 OtherNameComponent(OtherNameComponent),
649}
650
651impl PartialOrd for NameComponent {
652 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
653 Some(self.cmp(other))
654 }
655}
656
657impl Ord for NameComponent {
658 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
659 let mut self_repr = self.encode();
660 let mut other_repr = other.encode();
661
662 while self_repr.has_remaining() && other_repr.has_remaining() {
663 let self_cur = self_repr.get_u8();
664 let other_cur = other_repr.get_u8();
665
666 if self_cur < other_cur {
667 return std::cmp::Ordering::Less;
668 } else if self_cur > other_cur {
669 return std::cmp::Ordering::Greater;
670 }
671 }
672 std::cmp::Ordering::Equal
673 }
674}
675
676impl FromUriPart for NameComponent {
677 fn from_uri_part(segment: &[u8]) -> Option<Self> {
678 if segment.starts_with(b"sha256digest=") {
679 ImplicitSha256DigestComponent::from_uri_part(segment)
680 .map(Self::ImplicitSha256DigestComponent)
681 } else if segment.starts_with(b"params-sha256=") {
682 ParametersSha256DigestComponent::from_uri_part(segment)
683 .map(Self::ParametersSha256DigestComponent)
684 } else if segment.starts_with(b"seg=") {
685 SegmentNameComponent::from_uri_part(segment).map(Self::SegmentNameComponent)
686 } else if segment.starts_with(b"off=") {
687 ByteOffsetNameComponent::from_uri_part(segment).map(Self::ByteOffsetNameComponent)
688 } else if segment.starts_with(b"v=") {
689 VersionNameComponent::from_uri_part(segment).map(Self::VersionNameComponent)
690 } else if segment.starts_with(b"t=") {
691 TimestampNameComponent::from_uri_part(segment).map(Self::TimestampNameComponent)
692 } else if segment.starts_with(b"seq=") {
693 SequenceNumNameComponent::from_uri_part(segment).map(Self::SequenceNumNameComponent)
694 } else {
695 let expr = regex::bytes::Regex::new(r"^([0-9]+)=").expect("failed to compile regex");
696 if let Some(captures) = expr.captures(segment) {
697 let prefix: usize = String::from_utf8(captures.get(1).unwrap().as_bytes().to_vec())
698 .ok()?
699 .parse()
700 .ok()?;
701 match prefix {
702 8 => {
703 GenericNameComponent::from_uri_part(segment).map(Self::GenericNameComponent)
704 }
705 1 => ImplicitSha256DigestComponent::from_uri_part(segment)
706 .map(Self::ImplicitSha256DigestComponent),
707 2 => ParametersSha256DigestComponent::from_uri_part(segment)
708 .map(Self::ParametersSha256DigestComponent),
709 32 => {
710 KeywordNameComponent::from_uri_part(segment).map(Self::KeywordNameComponent)
711 }
712 50 => {
713 SegmentNameComponent::from_uri_part(segment).map(Self::SegmentNameComponent)
714 }
715 52 => ByteOffsetNameComponent::from_uri_part(segment)
716 .map(Self::ByteOffsetNameComponent),
717 54 => {
718 VersionNameComponent::from_uri_part(segment).map(Self::VersionNameComponent)
719 }
720 56 => TimestampNameComponent::from_uri_part(segment)
721 .map(Self::TimestampNameComponent),
722 58 => SequenceNumNameComponent::from_uri_part(segment)
723 .map(Self::SequenceNumNameComponent),
724 _ => OtherNameComponent::from_uri_part(segment).map(Self::OtherNameComponent),
725 }
726 } else {
727 Some(NameComponent::GenericNameComponent(
728 GenericNameComponent::from_uri_part(segment)?,
729 ))
730 }
731 }
732 }
733}
734
735impl ToUriPart for NameComponent {
736 fn to_uri_part(&self) -> String {
737 match *self {
738 Self::GenericNameComponent(ref component) => component.to_uri_part(),
739 Self::ImplicitSha256DigestComponent(ref component) => component.to_uri_part(),
740 Self::ParametersSha256DigestComponent(ref component) => component.to_uri_part(),
741 Self::KeywordNameComponent(ref component) => component.to_uri_part(),
742 Self::SegmentNameComponent(ref component) => component.to_uri_part(),
743 Self::ByteOffsetNameComponent(ref component) => component.to_uri_part(),
744 Self::VersionNameComponent(ref component) => component.to_uri_part(),
745 Self::TimestampNameComponent(ref component) => component.to_uri_part(),
746 Self::SequenceNumNameComponent(ref component) => component.to_uri_part(),
747 Self::OtherNameComponent(ref component) => component.to_uri_part(),
748 }
749 }
750}
751
752#[derive(Debug, Tlv, PartialEq, Eq, Clone, Hash)]
759#[tlv(7)]
760pub struct Name {
761 pub components: Vec<NameComponent>,
763}
764
765impl PartialOrd for Name {
766 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
767 Some(self.cmp(other))
768 }
769}
770
771impl Ord for Name {
772 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
773 self.components.cmp(&other.components)
774 }
775}
776
777impl Name {
778 pub const fn empty() -> Self {
780 Name {
781 components: Vec::new(),
782 }
783 }
784
785 pub fn from_str(s: &str) -> Result<Self> {
788 let s = if !s.starts_with("ndn:") {
789 Cow::Owned(format!("ndn:{}", s))
790 } else {
791 Cow::Borrowed(s)
792 };
793
794 let uri = Url::parse(&s)?;
795 let path = uri.path();
796
797 let mut components = Vec::with_capacity(path.split("/").count());
798
799 for mut segment in path.split("/") {
800 if segment == "" {
801 continue;
802 }
803 if segment.bytes().all(|x| x == b'.') {
804 segment = &segment[3..];
805 }
806 let decoded = urlencoding::decode_binary(segment.as_bytes());
807 components.push(NameComponent::from_uri_part(&decoded).ok_or(NdnError::ParseError)?);
808 }
809
810 Ok(Name { components })
811 }
812
813 pub fn to_uri(&self) -> Url {
815 let path: String = itertools::intersperse(
816 self.components
817 .iter()
818 .map(ToUriPart::to_uri_part)
819 .map(Cow::Owned),
820 Cow::Borrowed("/"),
821 )
822 .collect();
823 Url::parse(&format!("ndn:/{}", path)).unwrap()
824 }
825
826 pub fn iter(&self) -> impl Iterator<Item = &NameComponent> {
828 self.components.iter()
829 }
830
831 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut NameComponent> {
833 self.components.iter_mut()
834 }
835
836 pub fn into_iter(self) -> impl Iterator<Item = NameComponent> {
838 self.components.into_iter()
839 }
840
841 pub fn join<T: TryInto<Self>>(&self, other: T) -> Self
850 where
851 <T as TryInto<Self>>::Error: std::fmt::Debug,
852 {
853 let other = other.try_into().expect("Invalid name component string");
854
855 let mut components = Vec::with_capacity(self.components.len() + other.components.len());
856 components.extend_from_slice(&self.components);
857 components.extend_from_slice(&other.components);
858 Self { components }
859 }
860
861 pub fn has_prefix(&self, prefix: &Name) -> bool {
863 if prefix.components.len() > self.components.len() {
864 return false;
865 }
866 for (s, p) in self.components.iter().zip(prefix.iter()) {
867 if s != p {
868 return false;
869 }
870 }
871 true
872 }
873
874 pub fn remove_prefix(&mut self, prefix: &Name) -> bool {
877 if !self.has_prefix(prefix) {
878 return false;
879 }
880
881 for _ in 0..prefix.components.len() {
882 self.components.remove(0);
883 }
884 true
885 }
886}
887
888impl std::fmt::Display for Name {
889 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
890 self.to_uri().fmt(f)
891 }
892}
893
894impl From<NameComponent> for Name {
895 fn from(value: NameComponent) -> Self {
896 Name {
897 components: vec![value],
898 }
899 }
900}
901
902impl TryFrom<&str> for Name {
903 type Error = NdnError;
904
905 fn try_from(value: &str) -> std::result::Result<Name, NdnError> {
906 Name::from_str(value)
907 }
908}
909
910impl FromIterator<NameComponent> for Name {
911 fn from_iter<T: IntoIterator<Item = NameComponent>>(iter: T) -> Self {
912 Self {
913 components: iter.into_iter().collect(),
914 }
915 }
916}
917
918impl Extend<NameComponent> for Name {
919 fn extend<T: IntoIterator<Item = NameComponent>>(&mut self, iter: T) {
920 self.components.extend(iter)
921 }
922}
923
924#[cfg(test)]
925mod tests {
926 use super::*;
927
928 #[test]
929 fn simple_name() {
930 let uri = "/hello/world";
931 let name = Name::from_str(uri).unwrap();
932 assert_eq!(
933 name,
934 Name {
935 components: vec![
936 NameComponent::GenericNameComponent(GenericNameComponent {
937 name: Bytes::from(&b"hello"[..])
938 }),
939 NameComponent::GenericNameComponent(GenericNameComponent {
940 name: Bytes::from(&b"world"[..])
941 })
942 ]
943 }
944 );
945 assert_eq!(name.to_uri(), Url::parse("ndn:/hello/world").unwrap());
946 }
947
948 #[test]
949 fn simple_name_with_schema() {
950 let uri = "ndn:/hello/world";
951 let name = Name::from_str(uri).unwrap();
952 assert_eq!(
953 name,
954 Name {
955 components: vec![
956 NameComponent::GenericNameComponent(GenericNameComponent {
957 name: Bytes::from(&b"hello"[..])
958 }),
959 NameComponent::GenericNameComponent(GenericNameComponent {
960 name: Bytes::from(&b"world"[..])
961 })
962 ]
963 }
964 );
965 assert_eq!(name.to_uri(), Url::parse("ndn:/hello/world").unwrap());
966 }
967
968 #[test]
969 fn name_with_digest() {
970 let uri = "/hello/world/sha256digest=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
971 let name = Name::from_str(uri).unwrap();
972 assert_eq!(
973 name,
974 Name {
975 components: vec![
976 NameComponent::GenericNameComponent(GenericNameComponent {
977 name: Bytes::from(&b"hello"[..])
978 }),
979 NameComponent::GenericNameComponent(GenericNameComponent {
980 name: Bytes::from(&b"world"[..])
981 }),
982 NameComponent::ImplicitSha256DigestComponent(ImplicitSha256DigestComponent {
983 name: [
984 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
985 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
986 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
987 ]
988 })
989 ]
990 }
991 );
992 assert_eq!(name.to_uri(), Url::parse(&format!("ndn:{}", uri)).unwrap());
993 }
994
995 #[test]
996 fn name_with_digest_direct() {
997 let uri = "/hello/world/1=%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef";
998 let name = Name::from_str(uri).unwrap();
999 assert_eq!(
1000 name,
1001 Name {
1002 components: vec![
1003 NameComponent::GenericNameComponent(GenericNameComponent {
1004 name: Bytes::from(&b"hello"[..])
1005 }),
1006 NameComponent::GenericNameComponent(GenericNameComponent {
1007 name: Bytes::from(&b"world"[..])
1008 }),
1009 NameComponent::ImplicitSha256DigestComponent(ImplicitSha256DigestComponent {
1010 name: [
1011 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
1012 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
1013 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
1014 ]
1015 })
1016 ]
1017 }
1018 );
1019 }
1020
1021 #[test]
1022 fn name_with_params_sha256() {
1023 let uri = "/hello/world/params-sha256=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
1024 let name = Name::from_str(uri).unwrap();
1025 assert_eq!(
1026 name,
1027 Name {
1028 components: vec![
1029 NameComponent::GenericNameComponent(GenericNameComponent {
1030 name: Bytes::from(&b"hello"[..])
1031 }),
1032 NameComponent::GenericNameComponent(GenericNameComponent {
1033 name: Bytes::from(&b"world"[..])
1034 }),
1035 NameComponent::ParametersSha256DigestComponent(
1036 ParametersSha256DigestComponent {
1037 name: [
1038 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE,
1039 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD,
1040 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
1041 ]
1042 }
1043 )
1044 ]
1045 }
1046 );
1047 assert_eq!(name.to_uri(), Url::parse(&format!("ndn:{}", uri)).unwrap());
1048 }
1049
1050 #[test]
1051 fn name_with_params_sha256_direct() {
1052 let uri = "/hello/world/2=%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef%de%ad%be%ef";
1053 let name = Name::from_str(uri).unwrap();
1054 assert_eq!(
1055 name,
1056 Name {
1057 components: vec![
1058 NameComponent::GenericNameComponent(GenericNameComponent {
1059 name: Bytes::from(&b"hello"[..])
1060 }),
1061 NameComponent::GenericNameComponent(GenericNameComponent {
1062 name: Bytes::from(&b"world"[..])
1063 }),
1064 NameComponent::ParametersSha256DigestComponent(
1065 ParametersSha256DigestComponent {
1066 name: [
1067 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE,
1068 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD,
1069 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
1070 ]
1071 }
1072 )
1073 ]
1074 }
1075 );
1076 }
1077
1078 #[test]
1079 fn dot2() {
1080 let uri = "/hello/../world";
1081 let name = Name::from_str(uri).unwrap();
1082 assert_eq!(
1083 name,
1084 Name {
1085 components: vec![NameComponent::GenericNameComponent(GenericNameComponent {
1086 name: Bytes::from(&b"world"[..])
1087 })]
1088 }
1089 );
1090 }
1091
1092 #[test]
1093 fn dot3() {
1094 let uri = "/.../world";
1095 let name = Name::from_str(uri).unwrap();
1096 assert_eq!(
1097 name,
1098 Name {
1099 components: vec![
1100 NameComponent::GenericNameComponent(GenericNameComponent {
1101 name: Bytes::from(&b""[..])
1102 }),
1103 NameComponent::GenericNameComponent(GenericNameComponent {
1104 name: Bytes::from(&b"world"[..])
1105 })
1106 ]
1107 }
1108 );
1109 assert_eq!(name.to_uri(), Url::parse(&format!("ndn:{}", uri)).unwrap());
1110 }
1111
1112 #[test]
1113 fn dot4() {
1114 let uri = "/..../world";
1115 let name = Name::from_str(uri).unwrap();
1116 assert_eq!(
1117 name,
1118 Name {
1119 components: vec![
1120 NameComponent::GenericNameComponent(GenericNameComponent {
1121 name: Bytes::from(&b"."[..])
1122 }),
1123 NameComponent::GenericNameComponent(GenericNameComponent {
1124 name: Bytes::from(&b"world"[..])
1125 })
1126 ]
1127 }
1128 );
1129 assert_eq!(name.to_uri(), Url::parse(&format!("ndn:{}", uri)).unwrap());
1130 }
1131
1132 #[test]
1133 fn name_join_name() {
1134 let name = Name::from_str("/hello").unwrap();
1135 let name2 = Name::from_str("/world").unwrap();
1136 assert_eq!(name.join(name2), Name::from_str("/hello/world").unwrap());
1137 }
1138
1139 #[test]
1140 fn name_join_component() {
1141 let name = Name::from_str("/hello").unwrap();
1142 let component = NameComponent::from_uri_part(b"world").unwrap();
1143 assert_eq!(
1144 name.join(component),
1145 Name::from_str("/hello/world").unwrap()
1146 );
1147 }
1148
1149 #[test]
1150 fn name_slash_str() {
1151 let name = Name::from_str("/hello").unwrap();
1152 assert_eq!(name.join("world"), Name::from_str("/hello/world").unwrap());
1153 }
1154
1155 #[test]
1156 fn name_keyword() {
1157 let uri = "ndn:/hello/32=PA/world";
1158 let name = Name::from_str(&uri).unwrap();
1159 assert_eq!(
1160 name,
1161 Name {
1162 components: vec![
1163 NameComponent::GenericNameComponent(GenericNameComponent {
1164 name: Bytes::from(&b"hello"[..])
1165 }),
1166 NameComponent::KeywordNameComponent(KeywordNameComponent {
1167 name: Bytes::from(&b"PA"[..])
1168 }),
1169 NameComponent::GenericNameComponent(GenericNameComponent {
1170 name: Bytes::from(&b"world"[..])
1171 }),
1172 ]
1173 }
1174 );
1175
1176 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1177 }
1178
1179 #[test]
1180 fn name_segment() {
1181 let uri = "ndn:/hello/seg=5/world";
1182 let name = Name::from_str(&uri).unwrap();
1183 assert_eq!(
1184 name,
1185 Name {
1186 components: vec![
1187 NameComponent::GenericNameComponent(GenericNameComponent {
1188 name: Bytes::from(&b"hello"[..])
1189 }),
1190 NameComponent::SegmentNameComponent(SegmentNameComponent {
1191 segment_number: NonNegativeInteger::U8(5)
1192 }),
1193 NameComponent::GenericNameComponent(GenericNameComponent {
1194 name: Bytes::from(&b"world"[..])
1195 }),
1196 ]
1197 }
1198 );
1199
1200 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1201 }
1202
1203 #[test]
1204 fn name_segment_binary() {
1205 let uri = "ndn:/hello/50=%05/world";
1206 let name = Name::from_str(&uri).unwrap();
1207 assert_eq!(
1208 name,
1209 Name {
1210 components: vec![
1211 NameComponent::GenericNameComponent(GenericNameComponent {
1212 name: Bytes::from(&b"hello"[..])
1213 }),
1214 NameComponent::SegmentNameComponent(SegmentNameComponent {
1215 segment_number: NonNegativeInteger::U8(5)
1216 }),
1217 NameComponent::GenericNameComponent(GenericNameComponent {
1218 name: Bytes::from(&b"world"[..])
1219 }),
1220 ]
1221 }
1222 );
1223 }
1224
1225 #[test]
1226 fn name_offset() {
1227 let uri = "ndn:/hello/off=5/world";
1228 let name = Name::from_str(&uri).unwrap();
1229 assert_eq!(
1230 name,
1231 Name {
1232 components: vec![
1233 NameComponent::GenericNameComponent(GenericNameComponent {
1234 name: Bytes::from(&b"hello"[..])
1235 }),
1236 NameComponent::ByteOffsetNameComponent(ByteOffsetNameComponent {
1237 offset: NonNegativeInteger::U8(5)
1238 }),
1239 NameComponent::GenericNameComponent(GenericNameComponent {
1240 name: Bytes::from(&b"world"[..])
1241 }),
1242 ]
1243 }
1244 );
1245
1246 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1247 }
1248
1249 #[test]
1250 fn name_offset_binary() {
1251 let uri = "ndn:/hello/52=%05/world";
1252 let name = Name::from_str(&uri).unwrap();
1253 assert_eq!(
1254 name,
1255 Name {
1256 components: vec![
1257 NameComponent::GenericNameComponent(GenericNameComponent {
1258 name: Bytes::from(&b"hello"[..])
1259 }),
1260 NameComponent::ByteOffsetNameComponent(ByteOffsetNameComponent {
1261 offset: NonNegativeInteger::U8(5)
1262 }),
1263 NameComponent::GenericNameComponent(GenericNameComponent {
1264 name: Bytes::from(&b"world"[..])
1265 }),
1266 ]
1267 }
1268 );
1269 }
1270
1271 #[test]
1272 fn name_version() {
1273 let uri = "ndn:/hello/v=5/world";
1274 let name = Name::from_str(&uri).unwrap();
1275 assert_eq!(
1276 name,
1277 Name {
1278 components: vec![
1279 NameComponent::GenericNameComponent(GenericNameComponent {
1280 name: Bytes::from(&b"hello"[..])
1281 }),
1282 NameComponent::VersionNameComponent(VersionNameComponent {
1283 version: NonNegativeInteger::U8(5)
1284 }),
1285 NameComponent::GenericNameComponent(GenericNameComponent {
1286 name: Bytes::from(&b"world"[..])
1287 }),
1288 ]
1289 }
1290 );
1291
1292 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1293 }
1294
1295 #[test]
1296 fn name_version_binary() {
1297 let uri = "ndn:/hello/54=%05/world";
1298 let name = Name::from_str(&uri).unwrap();
1299 assert_eq!(
1300 name,
1301 Name {
1302 components: vec![
1303 NameComponent::GenericNameComponent(GenericNameComponent {
1304 name: Bytes::from(&b"hello"[..])
1305 }),
1306 NameComponent::VersionNameComponent(VersionNameComponent {
1307 version: NonNegativeInteger::U8(5)
1308 }),
1309 NameComponent::GenericNameComponent(GenericNameComponent {
1310 name: Bytes::from(&b"world"[..])
1311 }),
1312 ]
1313 }
1314 );
1315 }
1316
1317 #[test]
1318 fn name_timestamp() {
1319 let uri = "ndn:/hello/t=5/world";
1320 let name = Name::from_str(&uri).unwrap();
1321 assert_eq!(
1322 name,
1323 Name {
1324 components: vec![
1325 NameComponent::GenericNameComponent(GenericNameComponent {
1326 name: Bytes::from(&b"hello"[..])
1327 }),
1328 NameComponent::TimestampNameComponent(TimestampNameComponent {
1329 time: NonNegativeInteger::U8(5)
1330 }),
1331 NameComponent::GenericNameComponent(GenericNameComponent {
1332 name: Bytes::from(&b"world"[..])
1333 }),
1334 ]
1335 }
1336 );
1337
1338 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1339 }
1340
1341 #[test]
1342 fn name_timestamp_binary() {
1343 let uri = "ndn:/hello/56=%05/world";
1344 let name = Name::from_str(&uri).unwrap();
1345 assert_eq!(
1346 name,
1347 Name {
1348 components: vec![
1349 NameComponent::GenericNameComponent(GenericNameComponent {
1350 name: Bytes::from(&b"hello"[..])
1351 }),
1352 NameComponent::TimestampNameComponent(TimestampNameComponent {
1353 time: NonNegativeInteger::U8(5)
1354 }),
1355 NameComponent::GenericNameComponent(GenericNameComponent {
1356 name: Bytes::from(&b"world"[..])
1357 }),
1358 ]
1359 }
1360 );
1361 }
1362
1363 #[test]
1364 fn name_sequence_num() {
1365 let uri = "ndn:/hello/seq=5/world";
1366 let name = Name::from_str(&uri).unwrap();
1367 assert_eq!(
1368 name,
1369 Name {
1370 components: vec![
1371 NameComponent::GenericNameComponent(GenericNameComponent {
1372 name: Bytes::from(&b"hello"[..])
1373 }),
1374 NameComponent::SequenceNumNameComponent(SequenceNumNameComponent {
1375 sequence_number: NonNegativeInteger::U8(5)
1376 }),
1377 NameComponent::GenericNameComponent(GenericNameComponent {
1378 name: Bytes::from(&b"world"[..])
1379 }),
1380 ]
1381 }
1382 );
1383
1384 assert_eq!(name.to_uri(), Url::parse(&uri).unwrap());
1385 }
1386
1387 #[test]
1388 fn name_sequence_num_binary() {
1389 let uri = "ndn:/hello/58=%05/world";
1390 let name = Name::from_str(&uri).unwrap();
1391 assert_eq!(
1392 name,
1393 Name {
1394 components: vec![
1395 NameComponent::GenericNameComponent(GenericNameComponent {
1396 name: Bytes::from(&b"hello"[..])
1397 }),
1398 NameComponent::SequenceNumNameComponent(SequenceNumNameComponent {
1399 sequence_number: NonNegativeInteger::U8(5)
1400 }),
1401 NameComponent::GenericNameComponent(GenericNameComponent {
1402 name: Bytes::from(&b"world"[..])
1403 }),
1404 ]
1405 }
1406 );
1407 }
1408
1409 #[test]
1410 fn name_order() {
1411 let mut names = [
1412 Name::from_str("ndn:/some/prefix/name/fgh").unwrap(),
1413 Name::from_str("ndn:/some/prefix/name/asd").unwrap(),
1414 Name::from_str("ndn:/some/prefix/name/sha256digest=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef").unwrap(),
1415 Name::from_str("ndn:/some/prefix").unwrap(),
1416 ];
1417 names.sort();
1418 assert_eq!(names, [
1419 Name::from_str("ndn:/some/prefix").unwrap(),
1420 Name::from_str("ndn:/some/prefix/name/sha256digest=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef").unwrap(),
1421 Name::from_str("ndn:/some/prefix/name/asd").unwrap(),
1422 Name::from_str("ndn:/some/prefix/name/fgh").unwrap(),
1423 ]);
1424 }
1425
1426 #[test]
1427 fn name_order_by_component_not_total_length() {
1428 let short_prefix = Name::from_str("/a/a").unwrap();
1431 let long_component = Name::from_str("/aa").unwrap();
1432
1433 assert_eq!(short_prefix.cmp(&long_component), std::cmp::Ordering::Less);
1434 }
1435}