Skip to content

Commit 0dec7e8

Browse files
committed
editoast: add the possibility of #[model(uom_unit="...")]
Signed-off-by: Tristram Gräbener <[email protected]>
1 parent a190bec commit 0dec7e8

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

editoast/editoast_derive/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ pub fn search_config_store(input: proc_macro::TokenStream) -> proc_macro::TokenS
217217
/// * `#[model(to_string)]`: calls `to_string()` before writing the field to the database and calls `String::from` after reading (diesel column type: String)
218218
/// * `#[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)
219219
/// * `#[model(remote = "T")]`: calls `Into::<T>::into` before writing the field to the database and calls `T::from` after reading (diesel column type: T)
220+
/// * `#[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"`
220221
/// * `#[model(geo)]` **TODO**: TBD
221222
///
222223
/// #### A note on identifiers

editoast/editoast_derive/src/model/args.rs

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub(super) struct ModelFieldArgs {
7979
pub(super) to_enum: bool,
8080
#[darling(default)]
8181
pub(super) remote: Option<syn::Type>,
82+
#[darling(default)]
83+
pub(super) uom_unit: Option<syn::Type>,
8284
}
8385

8486
impl GeneratedTypeArgs {

editoast/editoast_derive/src/model/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub(crate) enum FieldTransformation {
4545
Geo,
4646
ToString,
4747
ToEnum(syn::Type),
48+
UomUnit(syn::Type),
4849
}
4950

5051
#[derive(Debug, PartialEq)]
@@ -132,12 +133,14 @@ impl ModelField {
132133
Some(FieldTransformation::ToEnum(_)) => {
133134
parse_quote! { #expr as i16 }
134135
}
136+
Some(FieldTransformation::UomUnit(ref unit)) => parse_quote! { #expr.get::<#unit>() },
135137
None => parse_quote! { #expr },
136138
}
137139
}
138140

139141
#[allow(clippy::wrong_self_convention)]
140142
pub(crate) fn from_transformed(&self, expr: syn::Expr) -> syn::Expr {
143+
let ty = &self.ty;
141144
match self.transform {
142145
Some(FieldTransformation::Remote(_)) => parse_quote! { #expr.into() },
143146
Some(FieldTransformation::Json) => parse_quote! { #expr.0 },
@@ -146,6 +149,9 @@ impl ModelField {
146149
Some(FieldTransformation::ToEnum(ref ty)) => {
147150
parse_quote! { #ty::from_repr(#expr as usize).expect("Invalid variant repr") }
148151
}
152+
Some(FieldTransformation::UomUnit(ref unit)) => {
153+
parse_quote! { #ty::new::<#unit>(#expr) }
154+
}
149155
None => parse_quote! { #expr },
150156
}
151157
}
@@ -158,6 +164,7 @@ impl ModelField {
158164
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
159165
Some(FieldTransformation::ToString) => parse_quote! { String },
160166
Some(FieldTransformation::ToEnum(_)) => parse_quote! { i16 },
167+
Some(FieldTransformation::UomUnit(_)) => parse_quote! { f64 },
161168
None => ty.clone(),
162169
}
163170
}

editoast/editoast_derive/src/model/parsing.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ impl ModelField {
165165
value.geo,
166166
value.to_string,
167167
to_enum,
168+
value.uom_unit,
168169
)
169170
.map_err(|e| e.with_span(&ident))?;
170171
Ok(Self {
@@ -188,16 +189,18 @@ impl FieldTransformation {
188189
geo: bool,
189190
to_string: bool,
190191
to_enum: Option<syn::Type>,
192+
uom_unit: Option<syn::Type>,
191193
) -> darling::Result<Option<Self>> {
192-
match (remote, json, geo, to_string, to_enum) {
193-
(Some(ty), false, false, false, None) => Ok(Some(Self::Remote(ty))),
194-
(None, true, false, false, None) => Ok(Some(Self::Json)),
195-
(None, false, true, false, None) => Ok(Some(Self::Geo)),
196-
(None, false, false, true, None) => Ok(Some(Self::ToString)),
197-
(None, false, false, false, Some(ty)) => Ok(Some(Self::ToEnum(ty))),
198-
(None, false, false, false, None) => Ok(None),
194+
match (remote, json, geo, to_string, to_enum, uom_unit) {
195+
(Some(ty), false, false, false, None, None) => Ok(Some(Self::Remote(ty))),
196+
(None, true, false, false, None, None) => Ok(Some(Self::Json)),
197+
(None, false, true, false, None, None) => Ok(Some(Self::Geo)),
198+
(None, false, false, true, None, None) => Ok(Some(Self::ToString)),
199+
(None, false, false, false, Some(ty), None) => Ok(Some(Self::ToEnum(ty))),
200+
(None, false, false, false, None, Some(ty)) => Ok(Some(Self::UomUnit(ty))),
201+
(None, false, false, false, None, None) => Ok(None),
199202
_ => Err(Error::custom(
200-
"Model: remote, json, geo, to_string and to_enum attributes are mutually exclusive",
203+
"Model: remote, json, geo, to_string, to_enum and uom_unit attributes are mutually exclusive",
201204
)),
202205
}
203206
}

0 commit comments

Comments
 (0)