runestick/
item.rs

1use crate::RawStr;
2use byteorder::{ByteOrder as _, NativeEndian, WriteBytesExt as _};
3use serde::{Deserialize, Serialize};
4use std::convert::TryFrom as _;
5use std::fmt;
6use std::hash;
7use std::hash::Hash as _;
8
9// Types available.
10const CRATE: u8 = 0;
11const STRING: u8 = 1;
12const ID: u8 = 2;
13
14/// How many bits the type of a tag takes up.
15const TYPE_BITS: usize = 2;
16/// Mask of the type of a tag.
17const TYPE_MASK: usize = (0b1 << TYPE_BITS) - 1;
18/// Total tag size in bytes.
19const TAG_BYTES: usize = 2;
20/// Max size of data stored.
21const MAX_DATA: usize = 0b1 << (TAG_BYTES * 8 - TYPE_BITS);
22
23/// The name of an item.
24///
25/// This is made up of a collection of strings, like `["foo", "bar"]`.
26/// This is indicated in rune as `foo::bar`.
27///
28/// # Panics
29///
30/// The max length of a string component is is 2**15 = 32768. Attempting to add
31/// a string larger than that will panic.
32///
33/// # Component encoding
34///
35/// A component is encoded as:
36/// * A two byte tag as a u16 in native endianess, indicating its type (least
37///   significant 2 bits) and data (most significant 15 bits).
38/// * If the type is a `STRING`, the data is treated as the length of the
39///   string. Any other type this the `data` is treated as the numeric id of the
40///   component.
41/// * If the type is a `STRING`, the tag is repeated at the end of it to allow
42///   for seeking backwards. This is **not** the case for other types. Since
43///   they are fixed size its not necessary.
44///
45/// So all in all, a string is encoded as:
46///
47/// ```text
48/// dddddddd dddddddt *string content* dddddddd dddddddt
49/// ```
50///
51/// And any other component is just the two bytes:
52///
53/// ```text
54/// dddddddd dddddddt
55/// ```
56#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
57pub struct Item {
58    content: Vec<u8>,
59}
60
61impl Item {
62    /// Construct an empty item.
63    pub const fn new() -> Self {
64        Self {
65            content: Vec::new(),
66        }
67    }
68
69    /// Construct a new item path.
70    pub fn with_item<I>(iter: I) -> Self
71    where
72        I: IntoIterator,
73        I::Item: IntoComponent,
74    {
75        let mut content = Vec::new();
76
77        for c in iter {
78            c.write_component(&mut content);
79        }
80
81        Self { content }
82    }
83
84    /// Construct item for a crate.
85    ///
86    /// # Examples
87    ///
88    /// ```rust
89    /// use runestick::{Item, ComponentRef};
90    ///
91    /// let item = Item::with_crate("std");
92    /// assert_eq!(item.as_crate(), Some("std"));
93    ///
94    /// let mut it = item.iter();
95    /// assert_eq!(it.next(), Some(ComponentRef::Crate("std")));
96    /// assert_eq!(it.next(), None);
97    /// ```
98    pub fn with_crate(name: &str) -> Self {
99        Self::with_item(&[ComponentRef::Crate(name)])
100    }
101
102    /// Create a crated item with the given name.
103    ///
104    /// # Examples
105    ///
106    /// ```rust
107    /// use runestick::{Item, ComponentRef};
108    ///
109    /// let item = Item::with_crate_item("std", &["option"]);
110    /// assert_eq!(item.as_crate(), Some("std"));
111    ///
112    /// let mut it = item.iter();
113    /// assert_eq!(it.next(), Some(ComponentRef::Crate("std")));
114    /// assert_eq!(it.next(), Some(ComponentRef::Str("option")));
115    /// assert_eq!(it.next(), None);
116    /// ```
117    pub fn with_crate_item<I>(name: &str, iter: I) -> Self
118    where
119        I: IntoIterator,
120        I::Item: IntoComponent,
121    {
122        let mut content = Vec::new();
123        ComponentRef::Crate(name).write_component(&mut content);
124
125        for c in iter {
126            c.write_component(&mut content);
127        }
128
129        Self { content }
130    }
131
132    /// Get the crate corresponding to the item.
133    ///
134    /// # Examples
135    ///
136    /// ```rust
137    /// use runestick::Item;
138    ///
139    /// let item = Item::with_crate("std");
140    /// assert_eq!(item.as_crate(), Some("std"));
141    ///
142    /// let item = Item::with_item(&["local"]);
143    /// assert_eq!(item.as_crate(), None);
144    /// ```
145    pub fn as_crate(&self) -> Option<&str> {
146        if let Some(ComponentRef::Crate(s)) = self.iter().next() {
147            Some(s)
148        } else {
149            None
150        }
151    }
152
153    /// Access the first component of this item.
154    ///
155    /// # Examples
156    ///
157    /// ```rust
158    /// use runestick::{ComponentRef, Item};
159    ///
160    /// let item = Item::with_item(&["foo", "bar"]);
161    /// assert_eq!(item.first(), Some(ComponentRef::Str("foo")));
162    /// ```
163    pub fn first(&self) -> Option<ComponentRef<'_>> {
164        self.iter().next()
165    }
166
167    /// Push the given component to the current item.
168    pub fn push<C>(&mut self, c: C)
169    where
170        C: IntoComponent,
171    {
172        c.write_component(&mut self.content);
173    }
174
175    /// Push the given component to the current item.
176    pub fn pop(&mut self) -> Option<Component> {
177        let mut it = self.iter();
178        let c = it.next_back()?.into_component();
179        let new_len = it.content.len();
180        self.content.resize(new_len, 0);
181        Some(c)
182    }
183
184    /// Extend the current item with an iterator.
185    pub fn extend<I>(&mut self, i: I)
186    where
187        I: IntoIterator,
188        I::Item: IntoComponent,
189    {
190        for c in i {
191            self.push(c);
192        }
193    }
194
195    /// Check if the item is empty.
196    ///
197    /// # Examples
198    ///
199    /// ```rust
200    /// use runestick::Item;
201    ///
202    /// let item = Item::new();
203    /// assert!(item.is_empty());
204    ///
205    /// let item = Item::with_crate("std");
206    /// assert!(!item.is_empty());
207    /// ```
208    pub fn is_empty(&self) -> bool {
209        self.content.is_empty()
210    }
211
212    /// Clear the current item.
213    pub fn clear(&mut self) {
214        self.content.clear();
215    }
216
217    /// Construct a new vector from the current item.
218    pub fn as_vec(&self) -> Vec<Component> {
219        self.iter()
220            .map(ComponentRef::into_component)
221            .collect::<Vec<_>>()
222    }
223
224    /// Convert into a vector from the current item.
225    pub fn into_vec(self) -> Vec<Component> {
226        self.into_iter().collect::<Vec<_>>()
227    }
228
229    /// If the item only contains one element, return that element.
230    pub fn as_local(&self) -> Option<&str> {
231        let mut it = self.iter();
232
233        match it.next_back_str() {
234            Some(last) if it.is_empty() => Some(last),
235            _ => None,
236        }
237    }
238
239    /// Join this path with another.
240    pub fn join<I>(&self, other: I) -> Self
241    where
242        I: IntoIterator,
243        I::Item: IntoComponent,
244    {
245        let mut content = self.content.clone();
246
247        for c in other {
248            c.write_component(&mut content);
249        }
250
251        Self { content }
252    }
253
254    /// Clone and extend the item path.
255    pub fn extended<C>(&self, part: C) -> Self
256    where
257        C: IntoComponent,
258    {
259        let mut content = self.content.clone();
260        part.write_component(&mut content);
261        Self { content }
262    }
263
264    /// Access the last component in the path.
265    pub fn last(&self) -> Option<ComponentRef<'_>> {
266        self.iter().next_back()
267    }
268
269    /// Implement an iterator.
270    pub fn iter(&self) -> Iter<'_> {
271        Iter {
272            content: &self.content,
273        }
274    }
275
276    /// Test if current item starts with another.
277    pub fn starts_with(&self, other: &Self) -> bool {
278        self.content.starts_with(&other.content)
279    }
280
281    /// Test if current is immediate super of `other`.
282    pub fn is_super_of(&self, other: &Self, n: usize) -> bool {
283        if self == other {
284            return true;
285        }
286
287        let mut it = other.iter();
288
289        for _ in 0..n {
290            if it.next_back().is_none() {
291                return false;
292            }
293
294            if self == it {
295                return true;
296            }
297        }
298
299        false
300    }
301
302    /// Get the ancestry of one module to another.
303    ///
304    /// This returns three things:
305    /// * The shared prefix between the current and the `other` path.
306    /// * The suffix to get to the `other` path from the shared prefix.
307    pub fn ancestry(&self, other: &Self) -> (Self, Self) {
308        let mut a = self.iter();
309        let mut b = other.iter();
310
311        let mut shared = Item::new();
312        let mut suffix = Item::new();
313
314        while let Some(v) = b.next() {
315            if let Some(u) = a.next() {
316                if u == v {
317                    shared.push(v);
318                    continue;
319                } else {
320                    suffix.push(v);
321                    suffix.extend(b);
322                    return (shared, suffix);
323                }
324            }
325
326            suffix.push(v);
327            break;
328        }
329
330        suffix.extend(b);
331        (shared, suffix)
332    }
333}
334
335/// Format implementation for item.
336///
337/// An empty item is formatted as `{root}`, because it refers to the topmost
338/// root module.
339///
340/// # Examples
341///
342/// ```rust
343/// use runestick::{Item, ComponentRef::*};
344///
345/// assert_eq!("{root}", Item::new().to_string());
346/// assert_eq!("hello::$0", Item::with_item(&[Str("hello"), Id(0)]).to_string());
347/// ```
348impl fmt::Display for Item {
349    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350        use std::fmt::Write;
351        let mut it = self.iter();
352
353        if let Some(last) = it.next_back() {
354            let mut buf = String::new();
355
356            for p in it {
357                write!(buf, "{}::", p)?;
358            }
359
360            write!(buf, "{}", last)?;
361            f.pad(&buf)
362        } else {
363            f.pad("{root}")
364        }
365    }
366}
367
368impl fmt::Debug for Item {
369    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370        write!(f, "Item({})", self)
371    }
372}
373
374impl<'a> IntoIterator for Item {
375    type IntoIter = std::vec::IntoIter<Component>;
376    type Item = Component;
377
378    fn into_iter(self) -> Self::IntoIter {
379        self.as_vec().into_iter()
380    }
381}
382
383impl<'a> IntoIterator for &'a Item {
384    type IntoIter = Iter<'a>;
385    type Item = ComponentRef<'a>;
386
387    fn into_iter(self) -> Self::IntoIter {
388        self.iter()
389    }
390}
391
392/// An item over the iterator.
393///
394/// Constructed using [Item::iter].
395pub struct Iter<'a> {
396    content: &'a [u8],
397}
398
399impl<'a> Iter<'a> {
400    /// Check if the iterator is empty.
401    pub fn is_empty(&self) -> bool {
402        self.content.is_empty()
403    }
404
405    /// Get the next component as a string.
406    ///
407    /// Will consume the next component in the iterator, but will only indicate
408    /// if the next component was present, and was a [Component::Str].
409    pub fn next_str(&mut self) -> Option<&'a str> {
410        match self.next()? {
411            ComponentRef::Str(s) => Some(s),
412            _ => None,
413        }
414    }
415
416    /// Get the next back as a string component.
417    ///
418    /// Will consume the next component in the iterator, but will only indicate
419    /// if the next component was present, and was a [Component::Str].
420    pub fn next_back_str(&mut self) -> Option<&'a str> {
421        match self.next_back()? {
422            ComponentRef::Str(s) => Some(s),
423            _ => None,
424        }
425    }
426}
427
428impl<'a> Iterator for Iter<'a> {
429    type Item = ComponentRef<'a>;
430
431    fn next(&mut self) -> Option<Self::Item> {
432        if self.content.is_empty() {
433            return None;
434        }
435
436        let (head_tag, content) = self.content.split_at(TAG_BYTES);
437        let (b, n) = read_tag(head_tag);
438
439        let c = match b {
440            CRATE => {
441                let (s, content, tail_tag) = read_string(content, n);
442                debug_assert_eq!(head_tag, tail_tag);
443                self.content = content;
444                return Some(ComponentRef::Crate(s));
445            }
446            STRING => {
447                let (s, content, tail_tag) = read_string(content, n);
448                debug_assert_eq!(head_tag, tail_tag);
449                self.content = content;
450                return Some(ComponentRef::Str(s));
451            }
452            ID => ComponentRef::Id(n),
453            b => panic!("unsupported control byte {:?}", b),
454        };
455
456        self.content = content;
457        return Some(c);
458
459        fn read_string<'a>(content: &'a [u8], n: usize) -> (&'a str, &'a [u8], &'a [u8]) {
460            let (buf, content) = content.split_at(n);
461
462            // consume the head tag.
463            let (tail_tag, content) = content.split_at(TAG_BYTES);
464
465            // Safety: we control the construction of the item.
466            let s = unsafe { std::str::from_utf8_unchecked(buf) };
467
468            (s, content, tail_tag)
469        }
470    }
471}
472
473impl<'a> DoubleEndedIterator for Iter<'a> {
474    fn next_back(&mut self) -> Option<Self::Item> {
475        if self.content.is_empty() {
476            return None;
477        }
478
479        let content = &self.content[..];
480        let (content, tail) = content.split_at(
481            content
482                .len()
483                .checked_sub(TAG_BYTES)
484                .expect("length underflow"),
485        );
486        let (b, n) = read_tag(tail);
487
488        let c = match b {
489            CRATE => {
490                let (s, content) = read_string_back(content, n);
491                self.content = content;
492                return Some(ComponentRef::Crate(s));
493            }
494            STRING => {
495                let (s, content) = read_string_back(content, n);
496                self.content = content;
497                return Some(ComponentRef::Str(s));
498            }
499            ID => ComponentRef::Id(n),
500            b => panic!("unsupported control byte {:?}", b),
501        };
502
503        self.content = content;
504        return Some(c);
505
506        fn read_string_back<'a>(content: &'a [u8], n: usize) -> (&'a str, &'a [u8]) {
507            let (content, buf) =
508                content.split_at(content.len().checked_sub(n).expect("length underflow"));
509
510            // consume the head tag.
511            let (content, _) = content.split_at(
512                content
513                    .len()
514                    .checked_sub(TAG_BYTES)
515                    .expect("length underflow"),
516            );
517
518            // Safety: we control the construction of the item.
519            let s = unsafe { std::str::from_utf8_unchecked(buf) };
520
521            (s, content)
522        }
523    }
524}
525
526impl PartialEq<Item> for Iter<'_> {
527    fn eq(&self, other: &Item) -> bool {
528        self.content == other.content
529    }
530}
531
532impl PartialEq<&Item> for Iter<'_> {
533    fn eq(&self, other: &&Item) -> bool {
534        self.content == other.content
535    }
536}
537
538impl PartialEq<Iter<'_>> for Item {
539    fn eq(&self, other: &Iter<'_>) -> bool {
540        self.content == other.content
541    }
542}
543
544impl PartialEq<Iter<'_>> for &Item {
545    fn eq(&self, other: &Iter<'_>) -> bool {
546        self.content == other.content
547    }
548}
549
550/// The component of an item.
551///
552/// All indexes refer to sibling indexes. So two sibling id components could
553/// have the indexes `1` and `2` respectively.
554#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
555pub enum Component {
556    /// A crate component.
557    Crate(Box<str>),
558    /// A regular string component.
559    Str(Box<str>),
560    /// A nested anonymous part with an identifier.
561    Id(usize),
562}
563
564impl Component {
565    /// Get the identifier of the component.
566    pub fn id(&self) -> Option<usize> {
567        match self {
568            Self::Id(n) => Some(*n),
569            _ => None,
570        }
571    }
572
573    /// Convert into component reference.
574    pub fn as_component_ref(&self) -> ComponentRef<'_> {
575        match self {
576            Self::Crate(s) => ComponentRef::Crate(&*s),
577            Self::Str(s) => ComponentRef::Str(&*s),
578            Self::Id(n) => ComponentRef::Id(*n),
579        }
580    }
581}
582
583impl fmt::Display for Component {
584    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
585        match self {
586            Self::Crate(s) => write!(fmt, "::{}", s),
587            Self::Str(s) => write!(fmt, "{}", s),
588            Self::Id(n) => write!(fmt, "${}", n),
589        }
590    }
591}
592
593/// A reference to a component of an item.
594///
595/// All indexes refer to sibling indexes. So two sibling id components could
596/// have the indexes `1` and `2` respectively.
597#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
598pub enum ComponentRef<'a> {
599    /// A crate string component.
600    Crate(&'a str),
601    /// A regular string component.
602    Str(&'a str),
603    /// A nested anonymous part with an identifier.
604    Id(usize),
605}
606
607impl ComponentRef<'_> {
608    /// Get the identifier of the component if it is an identifier component.
609    pub fn id(self) -> Option<usize> {
610        match self {
611            Self::Id(n) => Some(n),
612            _ => None,
613        }
614    }
615
616    /// Convert into an owned component.
617    pub fn into_component(self) -> Component {
618        match self {
619            Self::Crate(s) => Component::Crate(s.into()),
620            Self::Str(s) => Component::Str(s.into()),
621            Self::Id(n) => Component::Id(n),
622        }
623    }
624
625    /// Write the current component to the given vector.
626    pub fn write_component(self, output: &mut Vec<u8>) {
627        match self {
628            ComponentRef::Crate(s) => {
629                write_crate(s, output);
630            }
631            ComponentRef::Str(s) => {
632                write_str(s, output);
633            }
634            ComponentRef::Id(c) => {
635                write_tag(output, ID, c);
636            }
637        }
638    }
639
640    /// Hash the current component to the given hasher.
641    pub fn hash_component<H>(self, hasher: &mut H)
642    where
643        H: hash::Hasher,
644    {
645        match self {
646            ComponentRef::Crate(s) => {
647                CRATE.hash(hasher);
648                s.hash(hasher);
649            }
650            ComponentRef::Str(s) => {
651                STRING.hash(hasher);
652                s.hash(hasher);
653            }
654            ComponentRef::Id(c) => {
655                ID.hash(hasher);
656                c.hash(hasher);
657            }
658        }
659    }
660}
661
662impl fmt::Display for ComponentRef<'_> {
663    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
664        match self {
665            Self::Crate(s) => write!(fmt, "::{}", s),
666            Self::Str(s) => write!(fmt, "{}", s),
667            Self::Id(n) => write!(fmt, "${}", n),
668        }
669    }
670}
671
672/// Trait for encoding the current type into a component.
673pub trait IntoComponent: Sized {
674    /// Convert into a component directly.
675    fn as_component_ref(&self) -> ComponentRef<'_>;
676
677    /// Convert into component.
678    fn into_component(self) -> Component {
679        ComponentRef::into_component(self.as_component_ref())
680    }
681
682    /// Write a component directly to a buffer.
683    fn write_component(self, output: &mut Vec<u8>) {
684        ComponentRef::write_component(self.as_component_ref(), output)
685    }
686
687    /// Hash the current component.
688    fn hash_component<H>(self, hasher: &mut H)
689    where
690        H: hash::Hasher,
691    {
692        ComponentRef::hash_component(self.as_component_ref(), hasher)
693    }
694}
695
696impl IntoComponent for ComponentRef<'_> {
697    fn as_component_ref(&self) -> ComponentRef<'_> {
698        *self
699    }
700
701    fn into_component(self) -> Component {
702        ComponentRef::into_component(self)
703    }
704}
705
706impl IntoComponent for &ComponentRef<'_> {
707    fn as_component_ref(&self) -> ComponentRef<'_> {
708        **self
709    }
710
711    fn into_component(self) -> Component {
712        ComponentRef::into_component(*self)
713    }
714}
715
716impl IntoComponent for Component {
717    fn as_component_ref(&self) -> ComponentRef<'_> {
718        Component::as_component_ref(self)
719    }
720
721    fn into_component(self) -> Component {
722        self
723    }
724}
725
726impl IntoComponent for &Component {
727    fn as_component_ref(&self) -> ComponentRef<'_> {
728        Component::as_component_ref(*self)
729    }
730
731    fn into_component(self) -> Component {
732        self.clone()
733    }
734}
735
736macro_rules! impl_into_component_for_str {
737    ($ty:ty, $slf:ident, $into:expr) => {
738        impl IntoComponent for $ty {
739            fn as_component_ref(&self) -> ComponentRef<'_> {
740                ComponentRef::Str(self.as_ref())
741            }
742
743            fn into_component($slf) -> Component {
744                Component::Str($into)
745            }
746
747            fn write_component(self, output: &mut Vec<u8>) {
748                write_str(self.as_ref(), output)
749            }
750
751            fn hash_component<H>(self, hasher: &mut H)
752            where
753                H: hash::Hasher,
754            {
755                hash_str(self.as_ref(), hasher);
756            }
757        }
758    }
759}
760
761impl_into_component_for_str!(&str, self, self.into());
762impl_into_component_for_str!(&&str, self, (*self).into());
763impl_into_component_for_str!(RawStr, self, (*self).into());
764impl_into_component_for_str!(&RawStr, self, (**self).into());
765impl_into_component_for_str!(String, self, self.into());
766impl_into_component_for_str!(&String, self, self.clone().into());
767impl_into_component_for_str!(std::borrow::Cow<'_, str>, self, self.as_ref().into());
768
769/// Read a single byte.
770///
771/// # Panics
772///
773/// Panics if the byte is not available.
774fn read_tag(content: &[u8]) -> (u8, usize) {
775    let n = NativeEndian::read_u16(content);
776    let n = usize::try_from(n).unwrap();
777    ((n & TYPE_MASK) as u8, n >> TYPE_BITS)
778}
779
780/// Helper function to write an identifier.
781///
782/// # Panics
783///
784/// Panics if the provided size cannot fit withing an identifier.
785fn write_tag(output: &mut Vec<u8>, tag: u8, n: usize) {
786    debug_assert!(tag as usize <= TYPE_MASK);
787    assert!(
788        n < MAX_DATA,
789        "item data overflow, index or string size larger than MAX_DATA"
790    );
791    let n = u16::try_from(n << TYPE_BITS | tag as usize).unwrap();
792    output.write_u16::<NativeEndian>(n).unwrap();
793}
794
795/// Internal function to write only the crate of a component.
796fn write_crate(s: &str, output: &mut Vec<u8>) {
797    write_tag(output, CRATE, s.len());
798    output.extend(s.as_bytes());
799    write_tag(output, CRATE, s.len());
800}
801
802/// Internal function to write only the string of a component.
803fn write_str(s: &str, output: &mut Vec<u8>) {
804    write_tag(output, STRING, s.len());
805    output.extend(s.as_bytes());
806    write_tag(output, STRING, s.len());
807}
808
809/// Internal function to hash the given string.
810fn hash_str<H>(string: &str, hasher: &mut H)
811where
812    H: hash::Hasher,
813{
814    STRING.hash(hasher);
815    string.hash(hasher);
816}
817
818#[cfg(test)]
819mod tests {
820    use super::{Component, ComponentRef, IntoComponent as _, Item};
821
822    #[test]
823    fn test_pop() {
824        let mut item = Item::new();
825
826        item.push("start");
827        item.push(ComponentRef::Id(1));
828        item.push(ComponentRef::Id(2));
829        item.push("middle");
830        item.push(ComponentRef::Id(3));
831        item.push("end");
832
833        assert_eq!(item.pop(), Some("end".into_component()));
834        assert_eq!(item.pop(), Some(Component::Id(3)));
835        assert_eq!(item.pop(), Some("middle".into_component()));
836        assert_eq!(item.pop(), Some(Component::Id(2)));
837        assert_eq!(item.pop(), Some(Component::Id(1)));
838        assert_eq!(item.pop(), Some("start".into_component()));
839        assert_eq!(item.pop(), None);
840
841        assert!(item.is_empty());
842    }
843
844    #[test]
845    fn test_iter() {
846        let mut item = Item::new();
847
848        item.push("start");
849        item.push(ComponentRef::Id(1));
850        item.push(ComponentRef::Id(2));
851        item.push("middle");
852        item.push(ComponentRef::Id(3));
853        item.push("end");
854
855        let mut it = item.iter();
856
857        assert_eq!(it.next(), Some("start".as_component_ref()));
858        assert_eq!(it.next(), Some(ComponentRef::Id(1)));
859        assert_eq!(it.next(), Some(ComponentRef::Id(2)));
860        assert_eq!(it.next(), Some("middle".as_component_ref()));
861        assert_eq!(it.next(), Some(ComponentRef::Id(3)));
862        assert_eq!(it.next(), Some("end".as_component_ref()));
863        assert_eq!(it.next(), None);
864
865        assert!(!item.is_empty());
866    }
867
868    #[test]
869    fn test_next_back_str() {
870        let mut item = Item::new();
871
872        item.push(ComponentRef::Crate("std"));
873        item.push("start");
874        item.push(ComponentRef::Id(1));
875        item.push(ComponentRef::Id(2));
876        item.push("middle");
877        item.push(ComponentRef::Id(3));
878        item.push("end");
879
880        let mut it = item.iter();
881
882        assert_eq!(it.next_back_str(), Some("end"));
883        assert_eq!(it.next_back(), Some(ComponentRef::Id(3)));
884        assert_eq!(it.next_back_str(), Some("middle"));
885        assert_eq!(it.next_back(), Some(ComponentRef::Id(2)));
886        assert_eq!(it.next_back(), Some(ComponentRef::Id(1)));
887        assert_eq!(it.next_back_str(), Some("start"));
888        assert_eq!(it.next_back(), Some(ComponentRef::Crate("std")));
889        assert_eq!(it.next_back(), None);
890    }
891
892    #[test]
893    fn alternate() {
894        let mut item = Item::new();
895
896        item.push(ComponentRef::Crate("std"));
897        item.push("start");
898        item.push(ComponentRef::Id(1));
899        item.push(ComponentRef::Id(2));
900        item.push("middle");
901        item.push(ComponentRef::Id(3));
902        item.push("end");
903
904        let mut it = item.iter();
905
906        assert_eq!(it.next(), Some(ComponentRef::Crate("std")));
907        assert_eq!(it.next_str(), Some("start"));
908        assert_eq!(it.next_back_str(), Some("end"));
909        assert_eq!(it.next(), Some(ComponentRef::Id(1)));
910        assert_eq!(it.next(), Some(ComponentRef::Id(2)));
911        assert_eq!(it.next_back(), Some(ComponentRef::Id(3)));
912        assert_eq!(it.next_str(), Some("middle"));
913        assert_eq!(it.next_back(), None);
914        assert_eq!(it.next(), None);
915    }
916
917    #[test]
918    fn store_max_data() {
919        let mut item = Item::new();
920        item.push(ComponentRef::Id(super::MAX_DATA - 1));
921        assert_eq!(item.last(), Some(ComponentRef::Id(super::MAX_DATA - 1)));
922    }
923
924    #[test]
925    fn store_max_string() {
926        let mut item = Item::new();
927        let s = std::iter::repeat('x')
928            .take(super::MAX_DATA - 1)
929            .collect::<String>();
930        item.push(ComponentRef::Str(&s));
931        assert_eq!(item.last(), Some(ComponentRef::Str(&s)));
932    }
933
934    #[test]
935    #[should_panic(expected = "item data overflow, index or string size larger than MAX_DATA")]
936    fn store_max_data_overflow() {
937        let mut item = Item::new();
938        item.push(ComponentRef::Id(super::MAX_DATA));
939        assert_eq!(item.last(), Some(ComponentRef::Id(super::MAX_DATA)));
940    }
941
942    #[test]
943    #[should_panic(expected = "item data overflow, index or string size larger than MAX_DATA")]
944    fn store_max_string_overflow() {
945        let mut item = Item::new();
946        let s = std::iter::repeat('x')
947            .take(super::MAX_DATA)
948            .collect::<String>();
949        item.push(ComponentRef::Str(&s));
950    }
951
952    #[test]
953    fn test_is_super_of() {
954        assert!(Item::new().is_super_of(&Item::new(), 1));
955        assert!(!Item::with_item(&["a"]).is_super_of(&Item::new(), 1));
956
957        assert!(!Item::with_item(&["a", "b"]).is_super_of(&Item::with_item(&["a"]), 1));
958        assert!(Item::with_item(&["a", "b"]).is_super_of(&Item::with_item(&["a", "b"]), 1));
959        assert!(!Item::with_item(&["a"]).is_super_of(&Item::with_item(&["a", "b", "c"]), 1));
960    }
961
962    #[test]
963    fn test_ancestry() {
964        assert_eq!(
965            (Item::new(), Item::new()),
966            Item::new().ancestry(&Item::new())
967        );
968
969        assert_eq!(
970            (Item::new(), Item::with_item(&["a"])),
971            Item::new().ancestry(&Item::with_item(&["a"]))
972        );
973
974        assert_eq!(
975            (Item::new(), Item::with_item(&["a", "b"])),
976            Item::new().ancestry(&Item::with_item(&["a", "b"]))
977        );
978
979        assert_eq!(
980            (Item::with_item(&["a"]), Item::with_item(&["b"])),
981            Item::with_item(&["a", "c"]).ancestry(&Item::with_item(&["a", "b"]))
982        );
983
984        assert_eq!(
985            (Item::with_item(&["a", "b"]), Item::with_item(&["d", "e"])),
986            Item::with_item(&["a", "b", "c"]).ancestry(&Item::with_item(&["a", "b", "d", "e"]))
987        );
988    }
989}