use syntax::codemap::{Spanned, Span, dummy_spanned, DUMMY_SP};
use syntax::ext::base::ExtCtxt;
use syntax::tokenstream::TokenTree;
use syntax::ext::quote::rt::ToTokens;
use utils::span;
#[derive(Debug, Clone)]
pub struct KVSpanned<V> {
pub span: Span,
pub key: Spanned<String>,
pub value: Spanned<V>
}
impl<V> KVSpanned<V> {
pub fn map_ref<U, F: FnOnce(&V) -> U>(&self, f: F) -> KVSpanned<U> {
KVSpanned {
span: self.span,
key: self.key.clone(),
value: span(f(&self.value.node), self.value.span)
}
}
pub fn key(&self) -> &String {
&self.key.node
}
pub fn value(&self) -> &V {
&self.value.node
}
}
impl<T: Default> Default for KVSpanned<T> {
fn default() -> KVSpanned<T> {
dummy_kvspanned("", T::default())
}
}
impl<T: ToTokens> ToTokens for KVSpanned<T> {
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
self.value().to_tokens(cx)
}
}
pub fn dummy_kvspanned<T, S: ToString>(key: S, value: T) -> KVSpanned<T> {
KVSpanned {
span: DUMMY_SP,
key: dummy_spanned(key.to_string()),
value: dummy_spanned(value),
}
}