engine/transaction_derive/src/get_transaction.rs
2024-08-23 13:22:09 +02:00

95 lines
3.1 KiB
Rust

use quote::{quote, ToTokens};
use syn::Ident;
use crate::attribute_info::*;
use crate::data_type::*;
use crate::transaction_field::*;
pub struct GetTransaction<'a> {
pub variable_name: &'a Ident,
pub data_type: &'a DataType,
pub attribute_infos: &'a Vec<AttributeInfo>,
pub tracker: &'a Option<Ident>,
}
impl<'a> From<&'a TransactionField> for GetTransaction<'a> {
fn from(tf: &'a TransactionField) -> Self {
Self {
variable_name: &tf.variable_name,
data_type: &tf.data_type,
attribute_infos: &tf.attribute_infos,
tracker: &tf.tracker,
}
}
}
impl<'a> ToTokens for GetTransaction<'a> {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let var = &self.variable_name;
let tracker = self.tracker.as_ref().expect("tracker not set");
let quote = match &self.data_type {
DataType::Array(_array) => {
quote! {
for (index, inner) in self.#tracker.#var.iter_mut().enumerate() {
if let Some(v) = inner.take() {
use ron::to_string;
use serde::Serialize;
serialized_transactions.push_str(
&format!(
"{}:{}!{};",
stringify!(#var),
index,
to_string(&v)?
)
);
}
}
}
}
DataType::Vector(_vector) => {
quote! {
for (index, inner) in self.#tracker.#var.iter_mut().enumerate() {
if let Some(v) = inner.take() {
use ron::to_string;
use serde::Serialize;
serialized_transactions.push_str(
&format!(
"{}:{}!{};",
stringify!(#var),
index,
to_string(&v)?
)
);
}
}
}
}
DataType::Other(_ts) => {
quote! {
if let Some(v) = self.#tracker.#var.take() {
use ron::to_string;
use serde::Serialize;
serialized_transactions.push_str(
&format!(
"{}:{};",
stringify!(#var),
to_string(&v)?
)
);
}
}
}
};
// check features
AttributeInfo::set_features(&self.attribute_infos, tokens);
proc_macro2::TokenStream::from(quote).to_tokens(tokens);
}
}