Skip to content

Commit

Permalink
editoast_derive: add the possibility of #[model(uom_unit="...")]
Browse files Browse the repository at this point in the history
Signed-off-by: Tristram Gräbener <[email protected]>
  • Loading branch information
Tristramg committed Dec 5, 2024
1 parent ee4ecc5 commit 4e926ec
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 8 deletions.
1 change: 1 addition & 0 deletions editoast/editoast_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ pub fn search_config_store(input: proc_macro::TokenStream) -> proc_macro::TokenS
/// * `#[model(to_string)]`: calls `to_string()` before writing the field to the database and calls `String::from` after reading (diesel column type: String)
/// * `#[model(to_enum)]`: is converted as `u8` before writing the field to the database and calls `FromRepr::from_repr` after reading (diesel column type: TinyInt)
/// * `#[model(remote = "T")]`: calls `Into::<T>::into` before writing the field to the database and calls `T::from` after reading (diesel column type: T)
/// * `#[model(uom_unit = "T")]`: the field is an uom quantity and stored in the database in the unit `T`, e.g. `"uom::si::length::meter"`
/// * `#[model(geo)]` **TODO**: TBD
///
/// #### A note on identifiers
Expand Down
2 changes: 2 additions & 0 deletions editoast/editoast_derive/src/model/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub(super) struct ModelFieldArgs {
pub(super) to_enum: bool,
#[darling(default)]
pub(super) remote: Option<syn::Type>,
#[darling(default)]
pub(super) uom_unit: Option<syn::Type>,
}

impl GeneratedTypeArgs {
Expand Down
7 changes: 7 additions & 0 deletions editoast/editoast_derive/src/model/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub(crate) enum FieldTransformation {
Geo,
ToString,
ToEnum(syn::Type),
UomUnit(syn::Type),
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -132,12 +133,14 @@ impl ModelField {
Some(FieldTransformation::ToEnum(_)) => {
parse_quote! { #expr as i16 }
}
Some(FieldTransformation::UomUnit(ref unit)) => parse_quote! { #expr.get::<#unit>() },
None => parse_quote! { #expr },
}
}

#[allow(clippy::wrong_self_convention)]
pub(crate) fn from_transformed(&self, expr: syn::Expr) -> syn::Expr {
let ty = &self.ty;
match self.transform {
Some(FieldTransformation::Remote(_)) => parse_quote! { #expr.into() },
Some(FieldTransformation::Json) => parse_quote! { #expr.0 },
Expand All @@ -146,6 +149,9 @@ impl ModelField {
Some(FieldTransformation::ToEnum(ref ty)) => {
parse_quote! { #ty::from_repr(#expr as usize).expect("Invalid variant repr") }
}
Some(FieldTransformation::UomUnit(ref unit)) => {
parse_quote! { #ty::new::<#unit>(#expr) }
}
None => parse_quote! { #expr },
}
}
Expand All @@ -158,6 +164,7 @@ impl ModelField {
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
Some(FieldTransformation::ToString) => parse_quote! { String },
Some(FieldTransformation::ToEnum(_)) => parse_quote! { i16 },
Some(FieldTransformation::UomUnit(_)) => parse_quote! { f64 },
None => ty.clone(),
}
}
Expand Down
20 changes: 12 additions & 8 deletions editoast/editoast_derive/src/model/parsing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl ModelField {
value.geo,
value.to_string,
to_enum,
value.uom_unit,
)
.map_err(|e| e.with_span(&ident))?;
Ok(Self {
Expand All @@ -188,16 +189,19 @@ impl FieldTransformation {
geo: bool,
to_string: bool,
to_enum: Option<syn::Type>,
uom_unit: Option<syn::Type>,
) -> darling::Result<Option<Self>> {
match (remote, json, geo, to_string, to_enum) {
(Some(ty), false, false, false, None) => Ok(Some(Self::Remote(ty))),
(None, true, false, false, None) => Ok(Some(Self::Json)),
(None, false, true, false, None) => Ok(Some(Self::Geo)),
(None, false, false, true, None) => Ok(Some(Self::ToString)),
(None, false, false, false, Some(ty)) => Ok(Some(Self::ToEnum(ty))),
(None, false, false, false, None) => Ok(None),
match (remote, json, geo, to_string, to_enum, uom_unit) {
(Some(ty), false, false, false, None, None) => Ok(Some(Self::Remote(ty))),
(None, true, false, false, None, None) => Ok(Some(Self::Json)),
(None, false, true, false, None, None) => Ok(Some(Self::Geo)),
(None, false, false, true, None, None) => Ok(Some(Self::ToString)),
(None, false, false, false, Some(ty), None) => Ok(Some(Self::ToEnum(ty))),
//(None, false, false, false, None, Some(ty)) => Ok(Some(Self::Unit(ty))),
(None, false, false, false, None, Some(ty)) => Ok(Some(Self::UomUnit(ty))),
(None, false, false, false, None, None) => Ok(None),
_ => Err(Error::custom(
"Model: remote, json, geo, to_string and to_enum attributes are mutually exclusive",
"Model: remote, json, geo, to_string, uom_unit and to_enum attributes are mutually exclusive",
)),
}
}
Expand Down

0 comments on commit 4e926ec

Please sign in to comment.