119625d8cSopenharmony_ciuse proc_macro2::{Ident, Span, TokenStream};
219625d8cSopenharmony_ciuse quote::ToTokens;
319625d8cSopenharmony_ciuse syn::LitStr;
419625d8cSopenharmony_ci
519625d8cSopenharmony_ciuse std::ops::{Deref, DerefMut};
619625d8cSopenharmony_ci
719625d8cSopenharmony_ci/// An entity with a span attached.
819625d8cSopenharmony_ci#[derive(Debug, Copy, Clone)]
919625d8cSopenharmony_cipub struct Sp<T> {
1019625d8cSopenharmony_ci    val: T,
1119625d8cSopenharmony_ci    span: Span,
1219625d8cSopenharmony_ci}
1319625d8cSopenharmony_ci
1419625d8cSopenharmony_ciimpl<T> Sp<T> {
1519625d8cSopenharmony_ci    pub fn new(val: T, span: Span) -> Self {
1619625d8cSopenharmony_ci        Sp { val, span }
1719625d8cSopenharmony_ci    }
1819625d8cSopenharmony_ci
1919625d8cSopenharmony_ci    pub fn get(&self) -> &T {
2019625d8cSopenharmony_ci        &self.val
2119625d8cSopenharmony_ci    }
2219625d8cSopenharmony_ci
2319625d8cSopenharmony_ci    pub fn span(&self) -> Span {
2419625d8cSopenharmony_ci        self.span
2519625d8cSopenharmony_ci    }
2619625d8cSopenharmony_ci}
2719625d8cSopenharmony_ci
2819625d8cSopenharmony_ciimpl<T> Deref for Sp<T> {
2919625d8cSopenharmony_ci    type Target = T;
3019625d8cSopenharmony_ci
3119625d8cSopenharmony_ci    fn deref(&self) -> &T {
3219625d8cSopenharmony_ci        &self.val
3319625d8cSopenharmony_ci    }
3419625d8cSopenharmony_ci}
3519625d8cSopenharmony_ci
3619625d8cSopenharmony_ciimpl<T> DerefMut for Sp<T> {
3719625d8cSopenharmony_ci    fn deref_mut(&mut self) -> &mut T {
3819625d8cSopenharmony_ci        &mut self.val
3919625d8cSopenharmony_ci    }
4019625d8cSopenharmony_ci}
4119625d8cSopenharmony_ci
4219625d8cSopenharmony_ciimpl From<Ident> for Sp<String> {
4319625d8cSopenharmony_ci    fn from(ident: Ident) -> Self {
4419625d8cSopenharmony_ci        Sp {
4519625d8cSopenharmony_ci            val: ident.to_string(),
4619625d8cSopenharmony_ci            span: ident.span(),
4719625d8cSopenharmony_ci        }
4819625d8cSopenharmony_ci    }
4919625d8cSopenharmony_ci}
5019625d8cSopenharmony_ci
5119625d8cSopenharmony_ciimpl From<LitStr> for Sp<String> {
5219625d8cSopenharmony_ci    fn from(lit: LitStr) -> Self {
5319625d8cSopenharmony_ci        Sp {
5419625d8cSopenharmony_ci            val: lit.value(),
5519625d8cSopenharmony_ci            span: lit.span(),
5619625d8cSopenharmony_ci        }
5719625d8cSopenharmony_ci    }
5819625d8cSopenharmony_ci}
5919625d8cSopenharmony_ci
6019625d8cSopenharmony_ciimpl<'a> From<Sp<&'a str>> for Sp<String> {
6119625d8cSopenharmony_ci    fn from(sp: Sp<&'a str>) -> Self {
6219625d8cSopenharmony_ci        Sp::new(sp.val.into(), sp.span)
6319625d8cSopenharmony_ci    }
6419625d8cSopenharmony_ci}
6519625d8cSopenharmony_ci
6619625d8cSopenharmony_ciimpl<U, T: PartialEq<U>> PartialEq<U> for Sp<T> {
6719625d8cSopenharmony_ci    fn eq(&self, other: &U) -> bool {
6819625d8cSopenharmony_ci        self.val == *other
6919625d8cSopenharmony_ci    }
7019625d8cSopenharmony_ci}
7119625d8cSopenharmony_ci
7219625d8cSopenharmony_ciimpl<T: AsRef<str>> AsRef<str> for Sp<T> {
7319625d8cSopenharmony_ci    fn as_ref(&self) -> &str {
7419625d8cSopenharmony_ci        self.val.as_ref()
7519625d8cSopenharmony_ci    }
7619625d8cSopenharmony_ci}
7719625d8cSopenharmony_ci
7819625d8cSopenharmony_ciimpl<T: ToTokens> ToTokens for Sp<T> {
7919625d8cSopenharmony_ci    fn to_tokens(&self, stream: &mut TokenStream) {
8019625d8cSopenharmony_ci        // this is the simplest way out of correct ones to change span on
8119625d8cSopenharmony_ci        // arbitrary token tree I could come up with
8219625d8cSopenharmony_ci        let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
8319625d8cSopenharmony_ci            tt.set_span(self.span);
8419625d8cSopenharmony_ci            tt
8519625d8cSopenharmony_ci        });
8619625d8cSopenharmony_ci
8719625d8cSopenharmony_ci        stream.extend(tt);
8819625d8cSopenharmony_ci    }
8919625d8cSopenharmony_ci}
90