Skip to content

Commit

Permalink
Enums in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Artem-Romanenia committed Mar 22, 2024
1 parent 956a787 commit 8a29758
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 279 deletions.
42 changes: 38 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ let dto = PersonDto { id: 321, name: "Jack".into(), age: 23 };
let person: Person = dto.into();

assert_eq!(person.id, 321); assert_eq!(person.name, "Jack"); assert_eq!(person.age, 23);

// Starting from v0.4.2 o2o also supports enums:

enum Creature {
Person(Person),
Cat { nickname: String },
Dog(String),
Other
}

#[derive(o2o)]
#[from_owned(Creature)]
enum CreatureDto {
Person(#[map(~.into())] PersonDto),
Cat { nickname: String },
Dog(String),
Other
}

let creature = Creature::Cat { nickname: "Floppa".into() };
let dto: CreatureDto = creature.into();

if let CreatureDto::Cat { nickname } = dto { assert_eq!(nickname, "Floppa"); } else { assert!(false) }
```

And here's the code that `o2o` generates (from here on, generated code is produced by [rust-analyzer: Expand macro recursively](https://rust-analyzer.github.io/manual.html#expand-macro-recursively) command):
Expand All @@ -78,6 +101,17 @@ And here's the code that `o2o` generates (from here on, generated code is produc
}
}
}

impl std::convert::From<Creature> for CreatureDto {
fn from(value: Creature) -> CreatureDto {
match value {
Creature::Person(f0) => CreatureDto::Person(f0.into()),
Creature::Cat { nickname } => CreatureDto::Cat { nickname: nickname },
Creature::Dog(f0) => CreatureDto::Dog(f0),
Creature::Other => CreatureDto::Other,
}
}
}
```
</details>

Expand Down Expand Up @@ -107,8 +141,8 @@ And here's the code that `o2o` generates (from here on, generated code is produc
- [Additional o2o instruction available via `#[o2o(...)]` syntax](#additional-o2o-instruction-available-via-o2o-syntax)
- [Primitive type conversions](#primitive-type-conversions)
- [Repeat instructions](#repeat-instructions)
- [Contributions](#contributions)
- [License](#license)
- [Contributions](#contributions)
- [License](#license)

## Traits and `o2o` *trait instructions*

Expand Down Expand Up @@ -1518,11 +1552,11 @@ struct CarDto {
```
</details>

### Contributions
## Contributions

All issues, questions, pull requests are extremely welcome.

#### License
## License

<sup>
Licensed under either an <a href="LICENSE-APACHE">Apache License, Version
Expand Down
53 changes: 16 additions & 37 deletions o2o-impl/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::attr::{self};
use crate::attr::{FieldAttrs, StructAttrs};
use crate::attr::{MemberAttrs, DataTypeAttrs};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::Comma;
use syn::{Attribute, DataEnum, DataStruct, DeriveInput, Fields, Generics, Ident, Index, Member, Result};

pub(crate) struct Struct<'a> {
pub attrs: StructAttrs,
pub attrs: DataTypeAttrs,
pub ident: &'a Ident,
pub generics: &'a Generics,
pub fields: Vec<Field>,
Expand All @@ -29,7 +29,7 @@ impl<'a> Struct<'a> {

#[derive(Clone)]
pub(crate) struct Field {
pub attrs: FieldAttrs,
pub attrs: MemberAttrs,
pub idx: usize,
pub member: Member,
}
Expand Down Expand Up @@ -78,7 +78,7 @@ impl<'a> Field {
}

pub(crate) struct Enum<'a> {
pub attrs: StructAttrs,
pub attrs: DataTypeAttrs,
pub ident: &'a Ident,
pub generics: &'a Generics,
pub variants: Vec<Variant>
Expand All @@ -98,9 +98,9 @@ impl<'a> Enum<'a> {
}

pub(crate) struct Variant {
pub attrs: FieldAttrs,
pub attrs: MemberAttrs,
pub ident: Ident,
pub idx: usize,
_idx: usize,
pub fields: Vec<Field>,
pub named_fields: bool,
}
Expand Down Expand Up @@ -137,9 +137,9 @@ impl<'a> Variant {
fn from_syn(i: usize, variant: &'a syn::Variant, bark: bool) -> Result<Self> {
let fields = Field::multiple_from_syn(&variant.fields, bark)?;
Ok(Variant {
attrs: attr::get_field_attrs(SynDataTypeMember::Variant(&variant), bark)?,
attrs: attr::get_field_attrs(SynDataTypeMember::Variant(variant), bark)?,
ident: variant.ident.clone(),
idx: i,
_idx: i,
fields,
named_fields: matches!(&variant.fields, Fields::Named(_)),
})
Expand All @@ -154,12 +154,12 @@ pub(crate) enum DataType<'a> {
impl<'a> DataType<'a> {
pub fn get_ident(&'a self) -> &Ident {
match self {
DataType::Struct(s) => &s.ident,
DataType::Enum(e) => &e.ident
DataType::Struct(s) => s.ident,
DataType::Enum(e) => e.ident
}
}

pub fn get_attrs(&'a self) -> &'a StructAttrs {
pub fn get_attrs(&'a self) -> &'a DataTypeAttrs {
match self {
DataType::Struct(s) => &s.attrs,
DataType::Enum(e) => &e.attrs
Expand All @@ -168,38 +168,17 @@ impl<'a> DataType<'a> {

pub fn get_members(&'a self) -> Vec<DataTypeMember> {
match self {
DataType::Struct(s) => s.fields.iter().map(|x| DataTypeMember::Field(x)).collect(),
DataType::Enum(e) => e.variants.iter().map(|x| DataTypeMember::Variant(x)).collect()
DataType::Struct(s) => s.fields.iter().map(DataTypeMember::Field).collect(),
DataType::Enum(e) => e.variants.iter().map(DataTypeMember::Variant).collect()
}
}

pub fn get_generics(&'a self) -> &'a Generics {
match self {
DataType::Struct(s) => &s.generics,
DataType::Enum(e) => &e.generics
DataType::Struct(s) => s.generics,
DataType::Enum(e) => e.generics
}
}

// pub fn get_field(&'a self, ty: &TypePath) -> Option<&Field> {
// match self {
// DataType::Struct(s) => s.fields.iter().find(|f|
// f.attrs.field_attr_core(&Kind::OwnedInto, ty)
// .filter(|&g| g.wrapper).is_some()
// ),
// DataType::Enum(e) => None
// }
// }

// pub fn get_field_with_action(&'a self, ty: &TypePath) -> Option<(&Field, &Option<Action>)> {
// match self {
// DataType::Struct(s) => s.fields.iter().find_map(|f|
// f.attrs.field_attr_core(&Kind::RefInto, ty)
// .filter(|&g| g.wrapper)
// .map(|x| (f, &x.action))
// ),
// DataType::Enum(e) => None
// }
// }
}

pub(crate) enum SynDataTypeMember<'a> {
Expand All @@ -223,7 +202,7 @@ pub(crate) enum DataTypeMember<'a> {
}

impl<'a> DataTypeMember<'a> {
pub fn get_attrs(&'a self) -> &'a FieldAttrs {
pub fn get_attrs(&'a self) -> &'a MemberAttrs {
match self {
DataTypeMember::Field(f) => &f.attrs,
DataTypeMember::Variant(v) => &v.attrs
Expand Down
Loading

0 comments on commit 8a29758

Please sign in to comment.