1 use proc_macro2::{Ident, Span, TokenStream};
2 use quote::ToTokens;
3 use syn::LitStr;
4 
5 use std::ops::{Deref, DerefMut};
6 
7 /// An entity with a span attached.
8 #[derive(Debug, Copy, Clone)]
9 pub struct Sp<T> {
10     val: T,
11     span: Span,
12 }
13 
14 impl<T> Sp<T> {
new(val: T, span: Span) -> Self15     pub fn new(val: T, span: Span) -> Self {
16         Sp { val, span }
17     }
18 
get(&self) -> &T19     pub fn get(&self) -> &T {
20         &self.val
21     }
22 
span(&self) -> Span23     pub fn span(&self) -> Span {
24         self.span
25     }
26 }
27 
28 impl<T> Deref for Sp<T> {
29     type Target = T;
30 
deref(&self) -> &T31     fn deref(&self) -> &T {
32         &self.val
33     }
34 }
35 
36 impl<T> DerefMut for Sp<T> {
deref_mut(&mut self) -> &mut T37     fn deref_mut(&mut self) -> &mut T {
38         &mut self.val
39     }
40 }
41 
42 impl From<Ident> for Sp<String> {
from(ident: Ident) -> Self43     fn from(ident: Ident) -> Self {
44         Sp {
45             val: ident.to_string(),
46             span: ident.span(),
47         }
48     }
49 }
50 
51 impl From<LitStr> for Sp<String> {
from(lit: LitStr) -> Self52     fn from(lit: LitStr) -> Self {
53         Sp {
54             val: lit.value(),
55             span: lit.span(),
56         }
57     }
58 }
59 
60 impl<'a> From<Sp<&'a str>> for Sp<String> {
from(sp: Sp<&'a str>) -> Self61     fn from(sp: Sp<&'a str>) -> Self {
62         Sp::new(sp.val.into(), sp.span)
63     }
64 }
65 
66 impl<U, T: PartialEq<U>> PartialEq<U> for Sp<T> {
eq(&self, other: &U) -> bool67     fn eq(&self, other: &U) -> bool {
68         self.val == *other
69     }
70 }
71 
72 impl<T: AsRef<str>> AsRef<str> for Sp<T> {
as_ref(&self) -> &str73     fn as_ref(&self) -> &str {
74         self.val.as_ref()
75     }
76 }
77 
78 impl<T: ToTokens> ToTokens for Sp<T> {
to_tokens(&self, stream: &mut TokenStream)79     fn to_tokens(&self, stream: &mut TokenStream) {
80         // this is the simplest way out of correct ones to change span on
81         // arbitrary token tree I could come up with
82         let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
83             tt.set_span(self.span);
84             tt
85         });
86 
87         stream.extend(tt);
88     }
89 }
90