xmlparser/
strspan.rs

1use core::fmt;
2use core::ops::{Deref, Range};
3
4
5/// A string slice.
6///
7/// Like `&str`, but also contains the position in the input XML
8/// from which it was parsed.
9#[must_use]
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11pub struct StrSpan<'a> {
12    text: &'a str,
13    start: usize,
14}
15
16impl<'a> From<&'a str> for StrSpan<'a> {
17    #[inline]
18    fn from(text: &'a str) -> Self {
19        StrSpan {
20            text,
21            start: 0,
22        }
23    }
24}
25
26impl PartialEq<str> for StrSpan<'_> {
27    fn eq(&self, other: &str) -> bool {
28        self.text == other
29    }
30}
31
32impl PartialEq<&str> for StrSpan<'_> {
33    fn eq(&self, other: &&str) -> bool {
34        self.text == *other
35    }
36}
37
38impl PartialEq<StrSpan<'_>> for str {
39    fn eq(&self, other: &StrSpan<'_>) -> bool {
40        self == other.text
41    }
42}
43
44impl PartialEq<StrSpan<'_>> for &str {
45    fn eq(&self, other: &StrSpan<'_>) -> bool {
46        *self == other.text
47    }
48}
49
50impl<'a> StrSpan<'a> {
51    /// Constructs a new `StrSpan` from substring.
52    #[inline]
53    pub(crate) fn from_substr(text: &str, start: usize, end: usize) -> StrSpan {
54        debug_assert!(start <= end);
55        StrSpan { text: &text[start..end], start }
56    }
57
58    /// Returns `true` is self is empty.
59    pub fn is_empty(&self) -> bool {
60        self.text.is_empty()
61    }
62
63    /// Returns the start position of the span.
64    #[inline]
65    pub fn start(&self) -> usize {
66        self.start
67    }
68
69    /// Returns the end position of the span.
70    #[inline]
71    pub fn end(&self) -> usize {
72        self.start + self.text.len()
73    }
74
75    /// Returns the range of the span.
76    #[inline]
77    pub fn range(&self) -> Range<usize> {
78        self.start..self.end()
79    }
80
81    /// Returns the span as a string slice
82    #[inline]
83    pub fn as_str(&self) -> &'a str {
84        &self.text
85    }
86
87    /// Returns an underling string region as `StrSpan`.
88    #[inline]
89    pub(crate) fn slice_region(&self, start: usize, end: usize) -> StrSpan<'a> {
90        StrSpan::from_substr(self.text, start, end)
91    }
92}
93
94impl<'a> fmt::Debug for StrSpan<'a> {
95    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96        write!(f, "StrSpan({:?} {}..{})", self.as_str(), self.start(), self.end())
97    }
98}
99
100impl<'a> fmt::Display for StrSpan<'a> {
101    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102        write!(f, "{}", self.as_str())
103    }
104}
105
106impl<'a> Deref for StrSpan<'a> {
107    type Target = str;
108
109    fn deref(&self) -> &Self::Target {
110        self.text
111    }
112}