squawk_syntax/
token_text.rs

1// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/syntax/src/token_text.rs
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27//! Yet another version of owned string, backed by a syntax tree token.
28
29use std::{cmp::Ordering, fmt, ops};
30
31use rowan::GreenToken;
32use smol_str::SmolStr;
33
34pub struct TokenText<'a>(pub(crate) Repr<'a>);
35
36pub(crate) enum Repr<'a> {
37    Borrowed(&'a str),
38    Owned(GreenToken),
39}
40
41impl<'a> TokenText<'a> {
42    pub fn borrowed(text: &'a str) -> Self {
43        TokenText(Repr::Borrowed(text))
44    }
45
46    pub(crate) fn owned(green: GreenToken) -> Self {
47        TokenText(Repr::Owned(green))
48    }
49
50    pub fn as_str(&self) -> &str {
51        match &self.0 {
52            &Repr::Borrowed(it) => it,
53            Repr::Owned(green) => green.text(),
54        }
55    }
56}
57
58impl ops::Deref for TokenText<'_> {
59    type Target = str;
60
61    fn deref(&self) -> &str {
62        self.as_str()
63    }
64}
65impl AsRef<str> for TokenText<'_> {
66    fn as_ref(&self) -> &str {
67        self.as_str()
68    }
69}
70
71impl From<TokenText<'_>> for String {
72    fn from(token_text: TokenText<'_>) -> Self {
73        token_text.as_str().into()
74    }
75}
76
77impl From<TokenText<'_>> for SmolStr {
78    fn from(token_text: TokenText<'_>) -> Self {
79        SmolStr::new(token_text.as_str())
80    }
81}
82
83impl PartialEq<&'_ str> for TokenText<'_> {
84    fn eq(&self, other: &&str) -> bool {
85        self.as_str() == *other
86    }
87}
88impl PartialEq<TokenText<'_>> for &'_ str {
89    fn eq(&self, other: &TokenText<'_>) -> bool {
90        other == self
91    }
92}
93impl PartialEq<String> for TokenText<'_> {
94    fn eq(&self, other: &String) -> bool {
95        self.as_str() == other.as_str()
96    }
97}
98impl PartialEq<TokenText<'_>> for String {
99    fn eq(&self, other: &TokenText<'_>) -> bool {
100        other == self
101    }
102}
103impl PartialEq for TokenText<'_> {
104    fn eq(&self, other: &TokenText<'_>) -> bool {
105        self.as_str() == other.as_str()
106    }
107}
108impl Eq for TokenText<'_> {}
109impl Ord for TokenText<'_> {
110    fn cmp(&self, other: &Self) -> Ordering {
111        self.as_str().cmp(other.as_str())
112    }
113}
114impl PartialOrd for TokenText<'_> {
115    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
116        Some(self.cmp(other))
117    }
118}
119impl fmt::Display for TokenText<'_> {
120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121        fmt::Display::fmt(self.as_str(), f)
122    }
123}
124impl fmt::Debug for TokenText<'_> {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        fmt::Debug::fmt(self.as_str(), f)
127    }
128}