blob: 8b65e5bc6003ba4348c9986882da4ebcf398e7e5 [file] [log] [blame]
David Tolnay42f50292016-09-04 13:54:21 -07001use std::fmt::{self, Display};
David Tolnay42f50292016-09-04 13:54:21 -07002
David Tolnay55337722016-09-11 12:58:56 -07003#[derive(Debug, Clone, Eq, Hash)]
David Tolnay42f50292016-09-04 13:54:21 -07004pub struct Ident(String);
5
6impl Ident {
7 pub fn new<T: Into<Ident>>(t: T) -> Self {
8 t.into()
9 }
10}
11
12impl<'a> From<&'a str> for Ident {
13 fn from(s: &str) -> Self {
14 Ident(s.to_owned())
15 }
16}
17
18impl From<String> for Ident {
19 fn from(s: String) -> Self {
20 Ident(s)
21 }
22}
23
David Tolnayc1683102016-09-27 08:17:58 -070024impl From<usize> for Ident {
25 fn from(u: usize) -> Self {
26 Ident(u.to_string())
27 }
28}
29
David Tolnay26469072016-09-04 13:59:48 -070030impl AsRef<str> for Ident {
31 fn as_ref(&self) -> &str {
David Tolnay42f50292016-09-04 13:54:21 -070032 &self.0
33 }
34}
35
36impl Display for Ident {
37 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
38 self.0.fmt(formatter)
39 }
40}
David Tolnayb79ee962016-09-04 09:39:20 -070041
David Tolnaydaaf7742016-10-03 11:11:43 -070042impl<T: ?Sized> PartialEq<T> for Ident
43 where T: AsRef<str>
44{
David Tolnay55337722016-09-11 12:58:56 -070045 fn eq(&self, other: &T) -> bool {
46 self.0 == other.as_ref()
47 }
David Tolnayb79ee962016-09-04 09:39:20 -070048}
49
David Tolnay86eca752016-09-04 11:26:41 -070050#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -070051pub mod parsing {
52 use super::*;
David Tolnaye26baba2016-10-24 22:05:57 -070053 use nom::IResult;
54 use space::skip_whitespace;
55 use unicode_xid::UnicodeXID;
David Tolnay9d8f1972016-09-04 11:58:48 -070056
David Tolnaye26baba2016-10-24 22:05:57 -070057 pub fn ident(mut input: &str) -> IResult<&str, Ident> {
58 input = skip_whitespace(input);
59
60 let mut chars = input.char_indices();
61 match chars.next() {
62 Some((_, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {}
63 _ => return IResult::Error,
64 }
65
66 while let Some((i, ch)) = chars.next() {
67 if !UnicodeXID::is_xid_continue(ch) {
68 return IResult::Done(&input[i..], input[..i].into());
69 }
70 }
71
72 IResult::Done("", input.into())
David Tolnay9d8f1972016-09-04 11:58:48 -070073 }
David Tolnayb79ee962016-09-04 09:39:20 -070074}
David Tolnay26469072016-09-04 13:59:48 -070075
76#[cfg(feature = "printing")]
77mod printing {
78 use super::*;
79 use quote::{Tokens, ToTokens};
80
81 impl ToTokens for Ident {
82 fn to_tokens(&self, tokens: &mut Tokens) {
83 tokens.append(self.as_ref())
84 }
85 }
86}