use proc_macro2::Literal;
use quote::{ToTokens, format_ident, quote};
pub enum GeneratorMember {
Named(String),
Unnamed(usize),
}
impl ToTokens for GeneratorMember {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
tokens.extend(match self {
GeneratorMember::Named(s) => {
let s = format_ident!("{}", s);
quote!(self.#s)
}
GeneratorMember::Unnamed(n) => {
let n = Literal::usize_unsuffixed(*n);
quote!(self.#n)
}
})
}
}
pub struct GeneratorMeasurement {
pub name: String,
}
impl ToTokens for GeneratorMeasurement {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let name = &self.name;
tokens.extend(quote!(
.measurement(#name)
))
}
}
pub struct GeneratorTag {
pub name: String,
pub member: GeneratorMember,
}
impl ToTokens for GeneratorTag {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let name = &self.name;
let member = &self.member;
tokens.extend(quote!(
.tag(#name, &#member)
))
}
}
pub struct GeneratorField {
pub name: String,
pub member: GeneratorMember,
}
impl ToTokens for GeneratorField {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let name = &self.name;
let member = &self.member;
tokens.extend(quote!(
.field(#name, &#member)
))
}
}
pub struct GeneratorTimestamp {
pub member: GeneratorMember,
}
impl ToTokens for GeneratorTimestamp {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let member = &self.member;
tokens.extend(quote!(
.timestamp(&#member)
))
}
}
pub struct GeneratorImpl {
pub target: String,
pub measurement: GeneratorMeasurement,
pub tags: Vec<GeneratorTag>,
pub fields: Vec<GeneratorField>,
pub timestamp: Option<GeneratorTimestamp>,
}
impl ToTokens for GeneratorImpl {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let target = format_ident!("{}", &self.target);
let measurement = &self.measurement;
let tags = &self.tags;
let fields = &self.fields;
let builder_tokens = if let Some(timestamp) = &self.timestamp {
quote!(
line_protocol::LineProtocolBuilder::default()
#measurement
#(#tags)*
#(#fields)*
#timestamp
.build()
)
} else {
quote!(
line_protocol::LineProtocolBuilder::default()
#measurement
#(#tags)*
#(#fields)*
.build()
)
};
tokens.extend(quote!(
impl LineProtocol for #target {
fn to_line_protocol(&self) -> Option<String> {
#builder_tokens
}
}
));
}
}
impl GeneratorImpl {
pub fn tokenstream(&self) -> proc_macro2::TokenStream {
quote!(#self)
}
}