picojson/
json_string.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use core::ops::Deref;
4
5/// Represents a JSON string.
6///
7/// 'a is the lifetime of the original input buffer.
8/// 'b is the lifetime of the scratch buffer.
9#[derive(Debug, PartialEq, Eq)]
10pub enum String<'a, 'b> {
11    /// A raw slice from the original input, used when no un-escaping is needed.
12    Borrowed(&'a str),
13    /// A slice from the scratch buffer, used when a string had to be un-escaped.
14    Unescaped(&'b str),
15}
16
17impl String<'_, '_> {
18    /// Returns the string as a `&str`, whether borrowed or unescaped.
19    pub fn as_str(&self) -> &str {
20        match self {
21            String::Borrowed(s) => s,
22            String::Unescaped(s) => s,
23        }
24    }
25}
26
27impl AsRef<str> for String<'_, '_> {
28    fn as_ref(&self) -> &str {
29        self.as_str()
30    }
31}
32
33impl Deref for String<'_, '_> {
34    type Target = str;
35
36    fn deref(&self) -> &Self::Target {
37        match self {
38            String::Borrowed(s) => s,
39            String::Unescaped(s) => s,
40        }
41    }
42}
43
44impl core::fmt::Display for String<'_, '_> {
45    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46        f.write_str(self.as_str())
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_json_string_deref() {
56        let borrowed = String::Borrowed("test");
57        assert_eq!(&*borrowed, "test");
58        assert_eq!(borrowed.len(), 4);
59
60        // Test that it works as a string reference
61        fn takes_str(s: &str) -> usize {
62            s.len()
63        }
64        assert_eq!(takes_str(&borrowed), 4);
65    }
66}