use super::FieldType;
use quote::{__private::TokenStream, quote};
pub fn field_from_boltmap(name: &str, typ: &FieldType) -> TokenStream {
match typ {
FieldType::DateTimeUtc(_ty) => {
quote!(
value.get::<::chrono::DateTime<::chrono::FixedOffset>>(#name)
.map(|dt| dt.into())
.map_err(|e| ::cypher_dto::Error::MissingField(#name.to_owned()))?
)
}
FieldType::OptionDateTimeUtc(_ty) => {
quote!(
value.get::<::chrono::DateTime<::chrono::FixedOffset>>(#name)
.map(|dt| dt.into()).ok()
)
}
FieldType::Num(_ty, num) => {
let mut tokens = quote!(
value.get(#name).map_err(|e| ::cypher_dto::Error::MissingField(#name.to_owned()))?
);
if let Some(type_arg) = num.map_getter_type_arg() {
let cast_type = type_arg.to_type();
tokens = quote!(
value.get::<#cast_type>(#name).map_err(|e| ::cypher_dto::Error::MissingField(#name.to_owned()))?
);
}
if num.map_uses_try_from() {
let try_from_type = num.to_type();
tokens = quote!(
#try_from_type::try_from(#tokens)
.map_err(|_| ::cypher_dto::Error::TypeMismatch(#name.to_owned()))?
);
}
if let Some(type_arg) = num.map_cast() {
let cast_type = type_arg.to_type();
tokens = quote!(#tokens as #cast_type);
}
tokens
}
FieldType::OptionNum(_ty, num) => {
let mut get_call = quote!(
value.get(#name)
);
let mut some_inner = quote!(v);
if let Some(type_arg) = num.map_getter_type_arg() {
let cast_type = type_arg.to_type();
get_call = quote!(
value.get::<#cast_type>(#name)
);
}
if num.map_uses_try_from() {
some_inner = quote!(
v.try_into()
.map_err(|_| ::cypher_dto::Error::TypeMismatch(#name.to_owned()))?
);
}
if let Some(type_arg) = num.map_cast() {
let cast_type = type_arg.to_type();
some_inner = quote!(#some_inner as #cast_type);
}
quote!(
match #get_call {
Ok(v) => Some(#some_inner),
Err(_) => None,
}
)
}
FieldType::OptionOther(_ty) => {
quote!(
value.get(#name)
)
}
FieldType::Other(_ty) => {
quote!(
value.get(#name).map_err(|e| ::cypher_dto::Error::MissingField(#name.to_owned()))?
)
}
}
}