Skip to content

Commit 7b2c010

Browse files
committed
editoast: fix ModelV2 remote attribute
1 parent aced918 commit 7b2c010

File tree

3 files changed

+86
-14
lines changed

3 files changed

+86
-14
lines changed

editoast/editoast_derive/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ pub fn search_config_store(input: proc_macro::TokenStream) -> proc_macro::TokenS
263263
/// * `#[model(primary)]`: implies `identifier` ; marks the field as the primary key of the table
264264
/// * `#[model(json)]`: wraps the row field with `diesel_jsonb::JsonValue` (diesel column type: `diesel_jsonb::Json<T>`)
265265
/// * `#[model(to_string)]`: calls `to_string()` before writing the field to the database and calls `String::from` after reading (diesel column type: String)
266-
/// * `#[model(remote = T)]`: calls `Into::<T>::into` before writing the field to the database and calls `T::from` after reading (diesel column type: T)
266+
/// * `#[model(remote = "T")]`: calls `Into::<T>::into` before writing the field to the database and calls `T::from` after reading (diesel column type: T)
267267
/// * `#[model(geo)]` **TODO**: TBD
268268
///
269269
/// #### A note on identifiers

editoast/editoast_derive/src/modelv2.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ struct ModelFieldOption {
148148
#[darling(default)]
149149
to_string: bool,
150150
#[darling(default)]
151-
remote: Option<syn::Path>,
151+
remote: Option<syn::Type>,
152152
}
153153

154154
#[derive(Debug, PartialEq)]
@@ -178,15 +178,15 @@ struct ModelField {
178178

179179
#[derive(Debug, PartialEq, Clone)]
180180
enum FieldTransformation {
181-
Remote(syn::Path),
181+
Remote(syn::Type),
182182
Json,
183183
Geo,
184184
ToString,
185185
}
186186

187187
impl FieldTransformation {
188188
fn from_args(
189-
remote: Option<syn::Path>,
189+
remote: Option<syn::Type>,
190190
json: bool,
191191
geo: bool,
192192
to_string: bool,
@@ -230,10 +230,7 @@ impl ModelField {
230230
#[allow(clippy::wrong_self_convention)]
231231
fn into_transformed(&self, expr: TokenStream) -> TokenStream {
232232
match self.transform {
233-
Some(FieldTransformation::Remote(_)) => {
234-
let ty = &self.ty;
235-
quote! { Into::<#ty>::into(#expr) }
236-
}
233+
Some(FieldTransformation::Remote(_)) => quote! { #expr.into() },
237234
Some(FieldTransformation::Json) => quote! { diesel_json::Json(#expr) },
238235
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
239236
Some(FieldTransformation::ToString) => quote! { #expr.to_string() },
@@ -244,7 +241,7 @@ impl ModelField {
244241
#[allow(clippy::wrong_self_convention)]
245242
fn from_transformed(&self, expr: TokenStream) -> TokenStream {
246243
match self.transform {
247-
Some(FieldTransformation::Remote(ref ty)) => quote! { #ty::from(#expr) },
244+
Some(FieldTransformation::Remote(_)) => quote! { #expr.into() },
248245
Some(FieldTransformation::Json) => quote! { #expr.0 },
249246
Some(FieldTransformation::Geo) => unimplemented!("to be designed"),
250247
Some(FieldTransformation::ToString) => quote! { String::from(#expr.parse()) },

editoast/src/modelsv2/mod.rs

+80-5
Original file line numberDiff line numberDiff line change
@@ -886,21 +886,21 @@ where
886886
#[cfg(test)]
887887
mod tests {
888888
use crate::fixtures::tests::{db_pool, TestFixture};
889+
use crate::modelsv2::*;
889890
use editoast_derive::ModelV2;
890891
use itertools::Itertools;
891892
use std::collections::HashSet;
892893

893894
#[derive(Debug, Default, Clone, ModelV2)]
894895
#[model(table = crate::tables::document)]
895-
pub struct Document {
896-
pub id: i64,
897-
pub content_type: String,
898-
pub data: Vec<u8>,
896+
struct Document {
897+
id: i64,
898+
content_type: String,
899+
data: Vec<u8>,
899900
}
900901

901902
#[rstest::rstest]
902903
async fn test_batch() {
903-
use crate::modelsv2::*;
904904
let pool = db_pool();
905905
let mut conn = pool.get().await.unwrap();
906906
let changesets = (0..5).map(|i| {
@@ -971,4 +971,79 @@ mod tests {
971971
.unwrap()
972972
);
973973
}
974+
975+
#[rstest::rstest]
976+
async fn test_remote() {
977+
#[derive(Debug, Clone, PartialEq)]
978+
enum Data {
979+
Prefixed(u8),
980+
Raw(u8, u8),
981+
}
982+
983+
impl From<Vec<u8>> for Data {
984+
fn from(v: Vec<u8>) -> Self {
985+
match v.as_slice() {
986+
[0x42, x] => Data::Prefixed(*x),
987+
[x, y] => Data::Raw(*x, *y),
988+
_ => panic!("invalid 2-bytes data"),
989+
}
990+
}
991+
}
992+
993+
impl From<Data> for Vec<u8> {
994+
fn from(d: Data) -> Self {
995+
match d {
996+
Data::Prefixed(x) => vec![0x42, x],
997+
Data::Raw(x, y) => vec![x, y],
998+
}
999+
}
1000+
}
1001+
1002+
#[derive(Clone, ModelV2)]
1003+
#[model(table = crate::tables::document)]
1004+
struct Document {
1005+
id: i64,
1006+
content_type: String,
1007+
#[model(remote = "Vec<u8>")]
1008+
data: Data,
1009+
}
1010+
1011+
let pool = db_pool();
1012+
let mut conn = pool.get().await.unwrap();
1013+
let docs = Document::create_batch::<_, Vec<_>>(
1014+
&mut conn,
1015+
[
1016+
Document::changeset()
1017+
.content_type(String::from("text/plain"))
1018+
.data(Data::Prefixed(0x43)),
1019+
Document::changeset()
1020+
.content_type(String::from("text/plain"))
1021+
.data(Data::Raw(0, 1)),
1022+
],
1023+
)
1024+
.await
1025+
.unwrap()
1026+
.into_iter()
1027+
.map(|d| TestFixture::new(d, pool.clone()))
1028+
.collect::<Vec<_>>();
1029+
assert_eq!(docs.len(), 2);
1030+
1031+
let ids = docs.iter().map(|d| d.model.id).collect::<Vec<_>>();
1032+
assert_eq!(
1033+
Document::retrieve(&mut conn, ids[0])
1034+
.await
1035+
.unwrap()
1036+
.unwrap()
1037+
.data,
1038+
Data::Prefixed(0x43)
1039+
);
1040+
assert_eq!(
1041+
Document::retrieve(&mut conn, ids[1])
1042+
.await
1043+
.unwrap()
1044+
.unwrap()
1045+
.data,
1046+
Data::Raw(0, 1)
1047+
);
1048+
}
9741049
}

0 commit comments

Comments
 (0)