Skip to content

Commit 4e59765

Browse files
committed
editoast: add ToToken ModelV2 definition ChangesetFromModelImpl
1 parent 2f5d218 commit 4e59765

File tree

4 files changed

+61
-31
lines changed

4 files changed

+61
-31
lines changed

editoast/editoast_derive/src/modelv2.rs

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

3131
let model_from_row_impl = config.model_from_row_impl();
32-
let from_impls = config.make_from_impls();
32+
let changeset_from_model_impl = config.changeset_from_model_impl();
3333

3434
let cs_builder = config.make_builder(true);
3535
let patch_builder = config.make_builder(false);
@@ -45,8 +45,8 @@ pub fn model(input: &DeriveInput) -> Result<TokenStream> {
4545
#preferred_id_impl
4646

4747
#model_from_row_impl
48+
#changeset_from_model_impl
4849

49-
#from_impls
5050
#cs_builder
5151
#patch_builder
5252
#model_impls

editoast/editoast_derive/src/modelv2/codegen.rs

+14-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod changeset_decl;
2+
mod changeset_from_model;
23
mod identifiable_impl;
34
mod model_from_row_impl;
45
mod model_impl;
@@ -7,13 +8,15 @@ mod row_decl;
78

89
use proc_macro2::{Span, TokenStream};
910
use quote::quote;
11+
use syn::parse_quote;
1012

1113
use crate::modelv2::codegen::changeset_decl::ChangesetDecl;
1214
use crate::modelv2::codegen::changeset_decl::ChangesetFieldDecl;
1315
use crate::modelv2::codegen::model_impl::ModelImpl;
1416
use crate::modelv2::codegen::row_decl::RowDecl;
1517
use crate::modelv2::codegen::row_decl::RowFieldDecl;
1618

19+
use self::changeset_from_model::ChangesetFromModelImpl;
1720
use self::identifiable_impl::IdentifiableImpl;
1821
use self::model_from_row_impl::ModelFromRowImpl;
1922
use self::preferred_id_impl::PreferredIdImpl;
@@ -75,7 +78,7 @@ impl ModelConfig {
7578
.filter(|field| !field.builder_skip)
7679
.map(|field| {
7780
let ident = &field.ident;
78-
let expr = field.into_transformed(quote! { #ident });
81+
let expr = field.into_transformed(parse_quote! { #ident });
7982
let body = if changeset {
8083
quote! { self.#ident = Some(#expr) }
8184
} else {
@@ -153,26 +156,16 @@ impl ModelConfig {
153156
}
154157
}
155158

156-
pub fn make_from_impls(&self) -> TokenStream {
157-
let model = &self.model;
158-
let (cs_field, cs_value): (Vec<_>, Vec<_>) = self
159-
.iter_fields()
160-
.filter(|f| !self.is_primary(f))
161-
.map(|field| {
162-
let ident = &field.ident;
163-
(ident, field.into_transformed(quote! { model.#ident }))
164-
})
165-
.unzip();
166-
let cs_ident = self.changeset.ident();
167-
quote! {
168-
#[automatically_derived]
169-
impl From<#model> for #cs_ident {
170-
fn from(model: #model) -> Self {
171-
Self {
172-
#( #cs_field: Some(#cs_value) ),*
173-
}
174-
}
175-
}
159+
pub(crate) fn changeset_from_model_impl(&self) -> ChangesetFromModelImpl {
160+
ChangesetFromModelImpl {
161+
model: self.model.clone(),
162+
changeset: self.changeset.ident(),
163+
fields: self
164+
.fields
165+
.iter()
166+
.filter(|f| !self.is_primary(f))
167+
.cloned()
168+
.collect(),
176169
}
177170
}
178171

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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 ChangesetFromModelImpl {
8+
pub(super) model: syn::Ident,
9+
pub(super) changeset: syn::Ident,
10+
pub(super) fields: Vec<ModelField>,
11+
}
12+
13+
impl ToTokens for ChangesetFromModelImpl {
14+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
15+
let Self {
16+
model,
17+
changeset,
18+
fields,
19+
} = self;
20+
let np!(field, value): np!(vec2) = fields
21+
.iter()
22+
.map(|field| {
23+
let ident = &field.ident;
24+
let expr = field.into_transformed(parse_quote! { model.#ident });
25+
(ident, expr)
26+
})
27+
.unzip();
28+
tokens.extend(quote! {
29+
#[automatically_derived]
30+
impl From<#model> for #changeset {
31+
fn from(model: #model) -> Self {
32+
Self {
33+
#( #field: Some(#value) ),*
34+
}
35+
}
36+
}
37+
});
38+
}
39+
}

editoast/editoast_derive/src/modelv2/config.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use std::{
33
ops::{Deref, DerefMut},
44
};
55

6-
use proc_macro2::TokenStream;
7-
use quote::quote;
86
use syn::parse_quote;
97

108
use super::{args::GeneratedTypeArgs, identifier::Identifier};
@@ -112,16 +110,16 @@ impl ModelConfig {
112110

113111
impl ModelField {
114112
#[allow(clippy::wrong_self_convention)]
115-
pub fn into_transformed(&self, expr: TokenStream) -> TokenStream {
113+
pub fn into_transformed(&self, expr: syn::Expr) -> syn::Expr {
116114
match self.transform {
117-
Some(FieldTransformation::Remote(_)) => quote! { #expr.into() },
118-
Some(FieldTransformation::Json) => quote! { diesel_json::Json(#expr) },
115+
Some(FieldTransformation::Remote(_)) => parse_quote! { #expr.into() },
116+
Some(FieldTransformation::Json) => parse_quote! { diesel_json::Json(#expr) },
119117
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
120-
Some(FieldTransformation::ToString) => quote! { #expr.to_string() },
118+
Some(FieldTransformation::ToString) => parse_quote! { #expr.to_string() },
121119
Some(FieldTransformation::ToEnum(_)) => {
122-
quote! { #expr as i16 }
120+
parse_quote! { #expr as i16 }
123121
}
124-
None => quote! { #expr },
122+
None => parse_quote! { #expr },
125123
}
126124
}
127125

0 commit comments

Comments
 (0)