diff --git a/README.md b/README.md
index 7148a49..7a1e065 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,7 @@ And here's the code that `o2o` generates (from here on, generated code is produc
- [The (not so big) Problem](#the-not-so-big-problem)
- [Inline expressions](#inline-expressions)
- [Examples](#examples)
- - [Different field name](#different-field-name)
+ - [Different member name](#different-member-name)
- [Different field type](#different-field-type)
- [Nested structs](#nested-structs)
- [Nested collection](#nested-collection)
@@ -313,7 +313,7 @@ So finally, let's look at some examples.
## Examples
-### Different field name
+### Different member name
``` rust
use o2o::o2o;
@@ -323,14 +323,29 @@ struct Entity {
another_int: i16,
}
+enum EntityEnum {
+ Entity(Entity),
+ SomethingElse { field: i32 }
+}
+
#[derive(o2o)]
-#[from_ref(Entity)]
-#[ref_into_existing(Entity)]
+#[map_ref(Entity)]
struct EntityDto {
some_int: i32,
#[map(another_int)]
different_int: i16,
}
+
+#[derive(o2o)]
+#[map_ref(EntityEnum)]
+enum EntityEnumDto {
+ #[map(Entity)]
+ EntityDto(#[map(~.into())]EntityDto),
+ SomethingElse {
+ #[map(field, *~)]
+ f: i32
+ }
+}
```
View generated code
@@ -350,6 +365,23 @@ struct EntityDto {
other.another_int = self.different_int;
}
}
+
+ impl std::convert::From<&EntityEnum> for EntityEnumDto {
+ fn from(value: &EntityEnum) -> EntityEnumDto {
+ match value {
+ EntityEnum::Entity(f0) => EntityEnumDto::EntityDto(f0.into()),
+ EntityEnum::SomethingElse { field } => EntityEnumDto::SomethingElse { f: *field },
+ }
+ }
+ }
+ impl std::convert::Into for &EntityEnumDto {
+ fn into(self) -> EntityEnum {
+ match self {
+ EntityEnumDto::EntityDto(f0) => EntityEnum::Entity(f0.into()),
+ EntityEnumDto::SomethingElse { f } => EntityEnum::SomethingElse { field: *f },
+ }
+ }
+ }
```
@@ -485,9 +517,6 @@ struct Child {
#[map_owned(Entity)]
struct EntityDto {
some_int: i32,
- // Here field name as well as type are different, so we pass in field name and tilde inline expression.
- // Also, it doesn't hurt to use member trait instruction #[map()],
- // which is broader than trait instruction #[map_owned]
#[map(children, ~.iter().map(|p|p.into()).collect())]
children_vec: Vec
}
@@ -588,7 +617,7 @@ enum ZodiacSign {}
```
-In a reverse case, you need to use a struct level `#[ghost()]` instruction:
+In a reverse case, you need to use a struct level `#[ghosts()]` instruction:
``` rust
use o2o::o2o;
@@ -805,16 +834,12 @@ impl Employee {
#[derive(o2o)]
#[map(Employee)]
#[ghosts(
- // o2o supports closures with one input parameter.
- // This parameter represents instance on the other side of the conversion.
first_name: {@.get_first_name()},
last_name: {@.get_last_name()}
)]
struct EmployeeDto {
#[map(id)]
employee_id: i32,
- // '@.' is another flavor of 'inline expression'.
- // @ also represents instance on the other side of the conversion.
#[ghost(@.get_full_name())]
full_name: String,
diff --git a/o2o-impl/src/expand.rs b/o2o-impl/src/expand.rs
index a9f7ffe..28bd521 100644
--- a/o2o-impl/src/expand.rs
+++ b/o2o-impl/src/expand.rs
@@ -20,7 +20,6 @@ pub fn derive(node: &DeriveInput) -> Result {
let input = Enum::from_syn(node, data)?;
let input = DataType::Enum(&input);
validate(&input)?;
- //Ok(TokenStream::new())
Ok(struct_impl(input))
},
_ => Err(Error::new_spanned(
@@ -579,7 +578,7 @@ fn render_struct_line(
let index2 = Member::Unnamed(Index { index: idx as u32, span: Span::call_site() });
quote!(obj.#index2 = #obj #index;)
} else {
- let index = if ctx.destructured_src { format_ident!("f{}", index).to_token_stream() } else { index.to_token_stream() };
+ let index = if ctx.destructured_src { format_ident!("f{}", index.index).to_token_stream() } else { index.to_token_stream() };
quote!(#obj #index,)
},
(syn::Member::Unnamed(index), None, Kind::OwnedIntoExisting | Kind::RefIntoExisting, StructKindHint::Tuple | StructKindHint::Unspecified) => {
@@ -590,7 +589,7 @@ fn render_struct_line(
if f.attrs.has_parent_attr(&ctx.struct_attr.ty) {
if !ctx.kind.is_ref() { quote!((&value).into(),) } else { quote!(value.into(),) }
} else {
- let field_path = if ctx.destructured_src { get_field_path(&Member::Named(format_ident!("f{}", index))) } else { get_field_path(&f.member) };
+ let field_path = if ctx.destructured_src { get_field_path(&Member::Named(format_ident!("f{}", index.index))) } else { get_field_path(&f.member) };
quote!(#obj #field_path,)
},
(syn::Member::Unnamed(_), None, _, StructKindHint::Struct) => {
@@ -624,7 +623,7 @@ fn render_struct_line(
quote!(#ident: #right_side,)
},
(syn::Member::Unnamed(index), Some(attr), Kind::OwnedInto | Kind::RefInto, StructKindHint::Tuple | StructKindHint::Unspecified) => {
- let index = if ctx.destructured_src { Some(format_ident!("f{}", index).to_token_stream()) } else { Some(index.to_token_stream()) };
+ let index = if ctx.destructured_src { Some(format_ident!("f{}", index.index).to_token_stream()) } else { Some(index.to_token_stream()) };
let right_side = attr.get_action_or(index.clone(), ctx, || quote!(#obj #index));
quote!(#right_side,)
},
@@ -644,7 +643,7 @@ fn render_struct_line(
quote!(other.#field_path = #right_side;)
},
(syn::Member::Unnamed(index), Some(attr), Kind::FromOwned | Kind::FromRef, _) => {
- let or = Member::Named(format_ident!("f{}", index));
+ let or = Member::Named(format_ident!("f{}", index.index));
let right_side = attr.get_stuff(&obj, get_field_path, ctx, || if ctx.destructured_src { &or } else { &f.member});
quote!(#right_side,)
}
@@ -891,7 +890,7 @@ impl<'a> ApplicableAttr<'a> {
(Some(ident), Some(action)) => {
if let Member::Unnamed(index) = ident {
if ctx.destructured_src {
- let ident = Member::Named(format_ident!("f{}", index));
+ let ident = Member::Named(format_ident!("f{}", index.index));
quote_action(action, Some(field_path(&ident)), ctx)
} else { quote_action(action, Some(field_path(ident)), ctx)}
} else {