180 lines
5.6 KiB
Rust
180 lines
5.6 KiB
Rust
use quote::{format_ident, quote, ToTokens};
|
|
use syn::Ident;
|
|
|
|
use crate::attribute_info::*;
|
|
use crate::data_type::*;
|
|
use crate::transaction_field::*;
|
|
|
|
pub struct TrackerField<'a> {
|
|
pub variable_name: &'a Ident,
|
|
pub data_type: &'a DataType,
|
|
pub convert_type: Option<&'a proc_macro2::TokenStream>,
|
|
pub attribute_infos: &'a Vec<AttributeInfo>,
|
|
}
|
|
|
|
impl<'a> From<&'a TransactionField> for TrackerField<'a> {
|
|
fn from(transaction_field: &'a TransactionField) -> Self {
|
|
let convert_type = AttributeInfo::find_convert_type(&transaction_field.attribute_infos);
|
|
|
|
Self {
|
|
variable_name: &transaction_field.variable_name,
|
|
data_type: &transaction_field.data_type,
|
|
convert_type,
|
|
attribute_infos: &transaction_field.attribute_infos,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct TrackerDataType<'a> {
|
|
pub variable_name: &'a Ident,
|
|
pub data_type: &'a DataType,
|
|
pub convert_type: &'a Option<&'a proc_macro2::TokenStream>,
|
|
pub attribute_infos: &'a Vec<AttributeInfo>,
|
|
}
|
|
|
|
impl<'a> From<&'a TrackerField<'a>> for TrackerDataType<'a> {
|
|
fn from(tracker_field: &'a TrackerField) -> Self {
|
|
Self {
|
|
variable_name: &tracker_field.variable_name,
|
|
data_type: &tracker_field.data_type,
|
|
convert_type: &tracker_field.convert_type,
|
|
attribute_infos: &tracker_field.attribute_infos,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> ToTokens for TrackerDataType<'a> {
|
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
|
let variable_name = &self.variable_name;
|
|
let track = format_ident!("track_{}", variable_name);
|
|
let last_change = format_ident!("{}_last_change", variable_name);
|
|
|
|
// figure out the type of the variable
|
|
let quote = match self.data_type {
|
|
DataType::Array(array) => {
|
|
let length = &array.length;
|
|
|
|
match self.convert_type {
|
|
Some(convert_type) => {
|
|
quote! {
|
|
#variable_name: [Option<#convert_type>; #length],
|
|
}
|
|
}
|
|
None => {
|
|
let inner = &array.inner_type;
|
|
|
|
quote! {
|
|
#variable_name: [Option<#inner>; #length],
|
|
}
|
|
}
|
|
}
|
|
}
|
|
DataType::Vector(vector) => match self.convert_type {
|
|
Some(convert_type) => {
|
|
quote! {
|
|
#variable_name: Vec<Option<#convert_type>>,
|
|
}
|
|
}
|
|
None => {
|
|
let inner = &vector.inner_type;
|
|
|
|
quote! {
|
|
#variable_name: Vec<Option<#inner>>,
|
|
}
|
|
}
|
|
},
|
|
DataType::Other(ts) => match self.convert_type {
|
|
Some(convert_type) => {
|
|
quote! {
|
|
#variable_name: Option<#convert_type>,
|
|
}
|
|
}
|
|
None => {
|
|
quote! {
|
|
#variable_name: Option<#ts>,
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
// set variable type
|
|
proc_macro2::TokenStream::from(quote).to_tokens(tokens);
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
// flag, if variable gets tracked
|
|
proc_macro2::TokenStream::from(quote! {
|
|
#track: bool,
|
|
})
|
|
.to_tokens(tokens);
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
// track the time the variable got changed last time
|
|
proc_macro2::TokenStream::from(match self.data_type {
|
|
DataType::Array(array) => {
|
|
let length = &array.length;
|
|
|
|
quote! {#last_change: [std::time::Duration; #length],}
|
|
}
|
|
DataType::Vector(_) => {
|
|
quote! {#last_change: Vec<std::time::Duration>,}
|
|
}
|
|
DataType::Other(_) => {
|
|
quote! {#last_change: std::time::Duration,}
|
|
}
|
|
})
|
|
.to_tokens(tokens);
|
|
}
|
|
}
|
|
|
|
pub struct TrackerDefault<'a> {
|
|
pub variable_name: &'a Ident,
|
|
pub attribute_infos: &'a Vec<AttributeInfo>,
|
|
}
|
|
|
|
impl<'a> From<&'a TrackerDataType<'a>> for TrackerDefault<'a> {
|
|
fn from(tracker_field: &'a TrackerDataType) -> Self {
|
|
Self {
|
|
variable_name: &tracker_field.variable_name,
|
|
attribute_infos: &tracker_field.attribute_infos,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> ToTokens for TrackerDefault<'a> {
|
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
|
let variable_name = &self.variable_name;
|
|
let track = format_ident!("track_{}", variable_name);
|
|
let last_change = format_ident!("{}_last_change", variable_name);
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
proc_macro2::TokenStream::from(quote! {
|
|
#variable_name: Default::default(),
|
|
})
|
|
.to_tokens(tokens);
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
proc_macro2::TokenStream::from(quote! {
|
|
#track: true,
|
|
})
|
|
.to_tokens(tokens);
|
|
|
|
// check features
|
|
AttributeInfo::set_features(&self.attribute_infos, tokens);
|
|
|
|
proc_macro2::TokenStream::from(quote! {
|
|
#last_change: Default::default(),
|
|
})
|
|
.to_tokens(tokens);
|
|
}
|
|
}
|