blob: 3ffacc71ca43cd1854b442bb3b97e6de54a93726 [file] [log] [blame]
David Tolnayf733f7e2016-11-25 10:36:25 -08001use std::borrow::Cow;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use std::cmp::Ordering;
David Tolnay42f50292016-09-04 13:54:21 -07003use std::fmt::{self, Display};
Alex Crichtonccbb45d2017-05-23 10:58:24 -07004use std::hash::{Hash, Hasher};
David Tolnay42f50292016-09-04 13:54:21 -07005
Alex Crichtonccbb45d2017-05-23 10:58:24 -07006use proc_macro2::Symbol;
7
8use Span;
Alex Crichton954046c2017-05-30 21:49:42 -07009use tokens;
Alex Crichtonccbb45d2017-05-23 10:58:24 -070010
11#[derive(Clone)]
12pub struct Ident {
13 pub sym: Symbol,
14 pub span: Span,
15}
David Tolnay42f50292016-09-04 13:54:21 -070016
17impl Ident {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070018 pub fn new(sym: Symbol, span: Span) -> Self {
19 Ident {
20 sym: sym,
21 span: span,
22 }
David Tolnay42f50292016-09-04 13:54:21 -070023 }
24}
25
26impl<'a> From<&'a str> for Ident {
27 fn from(s: &str) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070028 Ident::new(s.into(), Span::default())
David Tolnay42f50292016-09-04 13:54:21 -070029 }
30}
31
Alex Crichton954046c2017-05-30 21:49:42 -070032impl From<tokens::Self_> for Ident {
33 fn from(tok: tokens::Self_) -> Self {
34 Ident::new("self".into(), tok.0)
35 }
36}
37
38impl From<tokens::CapSelf> for Ident {
39 fn from(tok: tokens::CapSelf) -> Self {
40 Ident::new("Self".into(), tok.0)
41 }
42}
43
44impl From<tokens::Super> for Ident {
45 fn from(tok: tokens::Super) -> Self {
46 Ident::new("super".into(), tok.0)
47 }
48}
49
David Tolnayf733f7e2016-11-25 10:36:25 -080050impl<'a> From<Cow<'a, str>> for Ident {
51 fn from(s: Cow<'a, str>) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052 Ident::new(s[..].into(), Span::default())
David Tolnayf733f7e2016-11-25 10:36:25 -080053 }
54}
55
David Tolnay42f50292016-09-04 13:54:21 -070056impl From<String> for Ident {
57 fn from(s: String) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070058 Ident::new(s[..].into(), Span::default())
David Tolnay42f50292016-09-04 13:54:21 -070059 }
60}
61
David Tolnayc1683102016-09-27 08:17:58 -070062impl From<usize> for Ident {
63 fn from(u: usize) -> Self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070064 Ident::new(u.to_string()[..].into(), Span::default())
David Tolnayc1683102016-09-27 08:17:58 -070065 }
66}
67
David Tolnay26469072016-09-04 13:59:48 -070068impl AsRef<str> for Ident {
69 fn as_ref(&self) -> &str {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070070 self.sym.as_str()
David Tolnay42f50292016-09-04 13:54:21 -070071 }
72}
73
74impl Display for Ident {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
76 self.sym.as_str().fmt(formatter)
77 }
78}
79
80impl fmt::Debug for Ident {
81 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
82 fmt::Debug::fmt(self.sym.as_str(), formatter)
David Tolnay42f50292016-09-04 13:54:21 -070083 }
84}
David Tolnayb79ee962016-09-04 09:39:20 -070085
David Tolnaydaaf7742016-10-03 11:11:43 -070086impl<T: ?Sized> PartialEq<T> for Ident
87 where T: AsRef<str>
88{
David Tolnay55337722016-09-11 12:58:56 -070089 fn eq(&self, other: &T) -> bool {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070090 self.as_ref() == other.as_ref()
91 }
92}
93
94impl Eq for Ident {}
95
96impl PartialOrd for Ident {
97 fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
98 Some(self.cmp(other))
99 }
100}
101
102impl Ord for Ident {
103 fn cmp(&self, other: &Ident) -> Ordering {
104 self.as_ref().cmp(other.as_ref())
105 }
106}
107
108impl Hash for Ident {
109 fn hash<H: Hasher>(&self, h: &mut H) {
110 self.as_ref().hash(h)
David Tolnay55337722016-09-11 12:58:56 -0700111 }
David Tolnayb79ee962016-09-04 09:39:20 -0700112}
113
David Tolnay86eca752016-09-04 11:26:41 -0700114#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700115pub mod parsing {
116 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700117 use proc_macro2::{TokenTree, TokenKind};
118 use synom::{Synom, IResult};
David Tolnay9d8f1972016-09-04 11:58:48 -0700119
Alex Crichton954046c2017-05-30 21:49:42 -0700120 impl Synom for Ident {
121 fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
122 let mut tokens = input.iter();
123 let token = match tokens.next() {
124 Some(token) => token,
125 None => return IResult::Error,
126 };
127 let word = match token.kind {
128 TokenKind::Word(s) => s,
129 _ => return IResult::Error,
130 };
131 if word.as_str().starts_with('\'') {
132 return IResult::Error
133 }
134 match word.as_str() {
Michael Layzell416724e2017-05-24 21:12:34 -0400135 // From https://doc.rust-lang.org/grammar.html#keywords
136 "abstract" | "alignof" | "as" | "become" | "box" | "break" | "const" | "continue" |
137 "crate" | "do" | "else" | "enum" | "extern" | "false" | "final" | "fn" | "for" |
138 "if" | "impl" | "in" | "let" | "loop" | "macro" | "match" | "mod" | "move" |
139 "mut" | "offsetof" | "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
140 "return" | "Self" | "self" | "sizeof" | "static" | "struct" | "super" | "trait" |
141 "true" | "type" | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" |
Alex Crichton954046c2017-05-30 21:49:42 -0700142 "while" | "yield" => return IResult::Error,
143 _ => {}
Michael Layzell416724e2017-05-24 21:12:34 -0400144 }
Alex Crichton954046c2017-05-30 21:49:42 -0700145
146 IResult::Done(tokens.as_slice(), Ident {
147 span: Span(token.span),
148 sym: word,
149 })
150 }
151
152 fn description() -> Option<&'static str> {
153 Some("identifier")
David Tolnay05f462f2016-10-24 22:19:42 -0700154 }
155 }
David Tolnayb79ee962016-09-04 09:39:20 -0700156}
David Tolnay26469072016-09-04 13:59:48 -0700157
158#[cfg(feature = "printing")]
159mod printing {
160 use super::*;
161 use quote::{Tokens, ToTokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700162 use proc_macro2::{TokenTree, TokenKind};
David Tolnay26469072016-09-04 13:59:48 -0700163
164 impl ToTokens for Ident {
165 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700166 tokens.append(TokenTree {
167 span: self.span.0,
168 kind: TokenKind::Word(self.sym),
169 })
David Tolnay26469072016-09-04 13:59:48 -0700170 }
171 }
172}