]> git.proxmox.com Git - rustc.git/blob - vendor/darling_core/src/util/ident_string.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / vendor / darling_core / src / util / ident_string.rs
1 use std::fmt;
2 use std::hash::{Hash, Hasher};
3
4 use proc_macro2::{Span, TokenStream};
5 use quote::ToTokens;
6 use syn::{Ident, Meta};
7
8 use {FromMeta, Result};
9
10 /// A wrapper for an `Ident` which also keeps the value as a string.
11 ///
12 /// This struct can be used to perform string comparisons and operations.
13 #[derive(Clone, PartialOrd, Ord)]
14 pub struct IdentString {
15 ident: Ident,
16 string: String,
17 }
18
19 impl IdentString {
20 /// Create a new `IdentString`.
21 pub fn new(ident: Ident) -> Self {
22 IdentString {
23 string: ident.to_string(),
24 ident,
25 }
26 }
27
28 /// Get the ident as a `proc_macro2::Ident`.
29 pub fn as_ident(&self) -> &Ident {
30 &self.ident
31 }
32
33 /// Get the ident as a string.
34 pub fn as_str(&self) -> &str {
35 &self.string
36 }
37
38 /// Get the location of this `Ident` in source.
39 pub fn span(&self) -> Span {
40 self.ident.span()
41 }
42
43 /// Apply some transform to the ident's string representation.
44 ///
45 /// # Panics
46 /// This will panic if the transform produces an invalid ident.
47 pub fn map<F, S>(self, map_fn: F) -> Self
48 where
49 F: FnOnce(String) -> S,
50 S: AsRef<str>,
51 {
52 let span = self.span();
53 let string = map_fn(self.string);
54 Ident::new(string.as_ref(), span).into()
55 }
56 }
57
58 impl AsRef<Ident> for IdentString {
59 fn as_ref(&self) -> &Ident {
60 self.as_ident()
61 }
62 }
63
64 impl AsRef<str> for IdentString {
65 fn as_ref(&self) -> &str {
66 self.as_str()
67 }
68 }
69
70 impl From<Ident> for IdentString {
71 fn from(ident: Ident) -> Self {
72 IdentString::new(ident)
73 }
74 }
75
76 impl From<IdentString> for Ident {
77 fn from(v: IdentString) -> Ident {
78 v.ident
79 }
80 }
81
82 impl From<IdentString> for String {
83 fn from(v: IdentString) -> String {
84 v.string
85 }
86 }
87
88 impl Eq for IdentString {}
89
90 impl PartialEq for IdentString {
91 fn eq(&self, rhs: &Self) -> bool {
92 self.ident == rhs.ident
93 }
94 }
95
96 impl PartialEq<String> for IdentString {
97 fn eq(&self, rhs: &String) -> bool {
98 self.as_str() == rhs
99 }
100 }
101
102 impl<'a> PartialEq<&'a str> for IdentString {
103 fn eq(&self, rhs: &&str) -> bool {
104 self.as_str() == *rhs
105 }
106 }
107
108 impl Hash for IdentString {
109 fn hash<H: Hasher>(&self, state: &mut H) {
110 self.ident.hash(state);
111 }
112 }
113
114 impl ToTokens for IdentString {
115 fn to_tokens(&self, tokens: &mut TokenStream) {
116 self.ident.to_tokens(tokens);
117 }
118 }
119
120 impl fmt::Debug for IdentString {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 write!(f, "{:?}", self.ident)
123 }
124 }
125
126 impl fmt::Display for IdentString {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(f, "{}", self.ident)
129 }
130 }
131
132 impl FromMeta for IdentString {
133 fn from_meta(item: &Meta) -> Result<Self> {
134 Ident::from_meta(item).map(IdentString::from)
135 }
136 }
137
138 #[cfg(test)]
139 mod tests {
140 use super::IdentString;
141
142 #[test]
143 fn convert() {
144 let i_str = IdentString::new(parse_quote!(t));
145 assert_eq!(i_str.as_str(), "t");
146 }
147
148 #[test]
149 fn map_transform() {
150 let i = IdentString::new(parse_quote!(my));
151 let after = i.map(|v| format!("var_{}", v));
152 assert_eq!(after, "var_my");
153 assert_eq!(after, String::from("var_my"));
154 }
155 }