aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/syntax/src/ast/node_ext.rs17
-rw-r--r--crates/syntax/src/lib.rs2
-rw-r--r--crates/syntax/src/token_text.rs77
3 files changed, 89 insertions, 7 deletions
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 6d7db5fb2..2772d7364 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -8,23 +8,23 @@ use parser::SyntaxKind;
8 8
9use crate::{ 9use crate::{
10 ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, 10 ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode},
11 SmolStr, SyntaxElement, SyntaxToken, T, 11 SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
12}; 12};
13 13
14impl ast::Lifetime { 14impl ast::Lifetime {
15 pub fn text(&self) -> SmolStr { 15 pub fn text(&self) -> TokenText {
16 text_of_first_token(self.syntax()) 16 text_of_first_token(self.syntax())
17 } 17 }
18} 18}
19 19
20impl ast::Name { 20impl ast::Name {
21 pub fn text(&self) -> SmolStr { 21 pub fn text(&self) -> TokenText {
22 text_of_first_token(self.syntax()) 22 text_of_first_token(self.syntax())
23 } 23 }
24} 24}
25 25
26impl ast::NameRef { 26impl ast::NameRef {
27 pub fn text(&self) -> SmolStr { 27 pub fn text(&self) -> TokenText {
28 text_of_first_token(self.syntax()) 28 text_of_first_token(self.syntax())
29 } 29 }
30 30
@@ -33,8 +33,11 @@ impl ast::NameRef {
33 } 33 }
34} 34}
35 35
36fn text_of_first_token(node: &SyntaxNode) -> SmolStr { 36fn text_of_first_token(node: &SyntaxNode) -> TokenText {
37 node.green().children().next().and_then(|it| it.into_token()).unwrap().text().into() 37 let first_token =
38 node.green().children().next().and_then(|it| it.into_token()).unwrap().to_owned();
39
40 TokenText(first_token)
38} 41}
39 42
40pub enum Macro { 43pub enum Macro {
@@ -376,7 +379,7 @@ impl fmt::Display for NameOrNameRef {
376} 379}
377 380
378impl NameOrNameRef { 381impl NameOrNameRef {
379 pub fn text(&self) -> SmolStr { 382 pub fn text(&self) -> TokenText {
380 match self { 383 match self {
381 NameOrNameRef::Name(name) => name.text(), 384 NameOrNameRef::Name(name) => name.text(),
382 NameOrNameRef::NameRef(name_ref) => name_ref.text(), 385 NameOrNameRef::NameRef(name_ref) => name_ref.text(),
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index 2a5c61171..90de6bef6 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -29,6 +29,7 @@ mod syntax_error;
29mod parsing; 29mod parsing;
30mod validation; 30mod validation;
31mod ptr; 31mod ptr;
32mod token_text;
32#[cfg(test)] 33#[cfg(test)]
33mod tests; 34mod tests;
34 35
@@ -55,6 +56,7 @@ pub use crate::{
55 SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, 56 SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken,
56 SyntaxTreeBuilder, 57 SyntaxTreeBuilder,
57 }, 58 },
59 token_text::TokenText,
58}; 60};
59pub use parser::{SyntaxKind, T}; 61pub use parser::{SyntaxKind, T};
60pub use rowan::{ 62pub use rowan::{
diff --git a/crates/syntax/src/token_text.rs b/crates/syntax/src/token_text.rs
new file mode 100644
index 000000000..d2ed0a12a
--- /dev/null
+++ b/crates/syntax/src/token_text.rs
@@ -0,0 +1,77 @@
1//! Yet another version of owned string, backed by a syntax tree token.
2
3use std::{cmp::Ordering, fmt, ops};
4
5pub struct TokenText(pub(crate) rowan::GreenToken);
6
7impl TokenText {
8 pub fn as_str(&self) -> &str {
9 self.0.text()
10 }
11}
12
13impl ops::Deref for TokenText {
14 type Target = str;
15
16 fn deref(&self) -> &str {
17 self.as_str()
18 }
19}
20impl AsRef<str> for TokenText {
21 fn as_ref(&self) -> &str {
22 self.as_str()
23 }
24}
25
26impl From<TokenText> for String {
27 fn from(token_text: TokenText) -> Self {
28 token_text.as_str().into()
29 }
30}
31
32impl PartialEq<&'_ str> for TokenText {
33 fn eq(&self, other: &&str) -> bool {
34 self.as_str() == *other
35 }
36}
37impl PartialEq<TokenText> for &'_ str {
38 fn eq(&self, other: &TokenText) -> bool {
39 other == self
40 }
41}
42impl PartialEq<String> for TokenText {
43 fn eq(&self, other: &String) -> bool {
44 self.as_str() == other.as_str()
45 }
46}
47impl PartialEq<TokenText> for String {
48 fn eq(&self, other: &TokenText) -> bool {
49 other == self
50 }
51}
52impl PartialEq for TokenText {
53 fn eq(&self, other: &TokenText) -> bool {
54 self.as_str() == other.as_str()
55 }
56}
57impl Eq for TokenText {}
58impl Ord for TokenText {
59 fn cmp(&self, other: &Self) -> Ordering {
60 self.as_str().cmp(other.as_str())
61 }
62}
63impl PartialOrd for TokenText {
64 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
65 Some(self.cmp(other))
66 }
67}
68impl fmt::Display for TokenText {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 fmt::Display::fmt(self.as_str(), f)
71 }
72}
73impl fmt::Debug for TokenText {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 fmt::Debug::fmt(self.as_str(), f)
76 }
77}