Skip to content

Commit f1d7dc2

Browse files
committed
editoast: add ToToken ModelV2 definition ModelFromRowImpl
1 parent 4d502cc commit f1d7dc2

File tree

4 files changed

+54
-23
lines changed

4 files changed

+54
-23
lines changed

editoast/editoast_derive/src/modelv2.rs

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub fn model(input: &DeriveInput) -> Result<TokenStream> {
2828
let identifiable_impls = config.identifiable_impls();
2929
let preferred_id_impl = config.preferred_id_impl();
3030

31+
let model_from_row_impl = config.model_from_row_impl();
3132
let from_impls = config.make_from_impls();
3233

3334
let cs_builder = config.make_builder(true);
@@ -43,6 +44,8 @@ pub fn model(input: &DeriveInput) -> Result<TokenStream> {
4344
#(#identifiable_impls)*
4445
#preferred_id_impl
4546

47+
#model_from_row_impl
48+
4649
#from_impls
4750
#cs_builder
4851
#patch_builder

editoast/editoast_derive/src/modelv2/codegen.rs

+10-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod changeset_decl;
22
mod identifiable_impl;
3+
mod model_from_row_impl;
34
mod model_impl;
45
mod preferred_id_impl;
56
mod row_decl;
@@ -14,6 +15,7 @@ use crate::modelv2::codegen::row_decl::RowDecl;
1415
use crate::modelv2::codegen::row_decl::RowFieldDecl;
1516

1617
use self::identifiable_impl::IdentifiableImpl;
18+
use self::model_from_row_impl::ModelFromRowImpl;
1719
use self::preferred_id_impl::PreferredIdImpl;
1820

1921
use super::utils::np;
@@ -143,15 +145,16 @@ impl ModelConfig {
143145
}
144146
}
145147

148+
pub(crate) fn model_from_row_impl(&self) -> ModelFromRowImpl {
149+
ModelFromRowImpl {
150+
model: self.model.clone(),
151+
row: self.row.ident(),
152+
fields: self.fields.clone(),
153+
}
154+
}
155+
146156
pub fn make_from_impls(&self) -> TokenStream {
147157
let model = &self.model;
148-
let (row_field, row_value): (Vec<_>, Vec<_>) = self
149-
.iter_fields()
150-
.map(|field| {
151-
let ident = &field.ident;
152-
(ident, field.from_transformed(quote! { row.#ident }))
153-
})
154-
.unzip();
155158
let (cs_field, cs_value): (Vec<_>, Vec<_>) = self
156159
.iter_fields()
157160
.filter(|f| !self.is_primary(f))
@@ -160,18 +163,8 @@ impl ModelConfig {
160163
(ident, field.into_transformed(quote! { model.#ident }))
161164
})
162165
.unzip();
163-
let row_ident = self.row.ident();
164166
let cs_ident = self.changeset.ident();
165167
quote! {
166-
#[automatically_derived]
167-
impl From<#row_ident> for #model {
168-
fn from(row: #row_ident) -> Self {
169-
Self {
170-
#( #row_field: #row_value ),*
171-
}
172-
}
173-
}
174-
175168
#[automatically_derived]
176169
impl From<#model> for #cs_ident {
177170
fn from(model: #model) -> Self {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::modelv2::utils::np;
2+
use crate::modelv2::ModelField;
3+
use quote::quote;
4+
use quote::ToTokens;
5+
use syn::parse_quote;
6+
7+
pub(crate) struct ModelFromRowImpl {
8+
pub(super) model: syn::Ident,
9+
pub(super) row: syn::Ident,
10+
pub(super) fields: Vec<ModelField>,
11+
}
12+
13+
impl ToTokens for ModelFromRowImpl {
14+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
15+
let Self { model, row, fields } = self;
16+
let np!(field, value): np!(vec2) = fields
17+
.iter()
18+
.map(|field| {
19+
let ident = &field.ident;
20+
let expr = field.from_transformed(parse_quote! { row.#ident });
21+
(ident, expr)
22+
})
23+
.unzip();
24+
tokens.extend(quote! {
25+
#[automatically_derived]
26+
impl From<#row> for #model {
27+
fn from(row: #row) -> Self {
28+
Self {
29+
#( #field: #value ),*
30+
}
31+
}
32+
}
33+
});
34+
}
35+
}

editoast/editoast_derive/src/modelv2/config.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,16 @@ impl ModelField {
126126
}
127127

128128
#[allow(clippy::wrong_self_convention)]
129-
pub fn from_transformed(&self, expr: TokenStream) -> TokenStream {
129+
pub fn from_transformed(&self, expr: syn::Expr) -> syn::Expr {
130130
match self.transform {
131-
Some(FieldTransformation::Remote(_)) => quote! { #expr.into() },
132-
Some(FieldTransformation::Json) => quote! { #expr.0 },
131+
Some(FieldTransformation::Remote(_)) => parse_quote! { #expr.into() },
132+
Some(FieldTransformation::Json) => parse_quote! { #expr.0 },
133133
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
134-
Some(FieldTransformation::ToString) => quote! { String::from(#expr.parse()) },
134+
Some(FieldTransformation::ToString) => parse_quote! { String::from(#expr.parse()) },
135135
Some(FieldTransformation::ToEnum(ref ty)) => {
136-
quote! { #ty::from_repr(#expr as usize).expect("Invalid variant repr") }
136+
parse_quote! { #ty::from_repr(#expr as usize).expect("Invalid variant repr") }
137137
}
138-
None => quote! { #expr },
138+
None => parse_quote! { #expr },
139139
}
140140
}
141141

0 commit comments

Comments
 (0)