Skip to content

Commit

Permalink
Turn Optional into an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavo-shigueo committed Nov 10, 2024
1 parent 69e9987 commit a562561
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 36 deletions.
9 changes: 3 additions & 6 deletions macros/src/attr/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ impl Attr for FieldAttr {
rename: self.rename.or(other.rename),
inline: self.inline || other.inline,
skip: self.skip || other.skip,
optional: Optional {
optional: self.optional.optional || other.optional.optional,
nullable: self.optional.nullable || other.optional.nullable,
},
optional: self.optional.or(other.optional),
flatten: self.flatten || other.flatten,

using_serde_with: self.using_serde_with || other.using_serde_with,
Expand Down Expand Up @@ -124,7 +121,7 @@ impl Attr for FieldAttr {
);
}

if self.optional.optional {
if let Optional::Optional { .. } = self.optional {
syn_err_spanned!(
field;
"`optional` is not compatible with `flatten`"
Expand All @@ -147,7 +144,7 @@ impl Attr for FieldAttr {
);
}

if self.optional.optional {
if let Optional::Optional { .. } = self.optional {
syn_err_spanned!(
field;
"`optional` cannot with tuple struct fields"
Expand Down
30 changes: 23 additions & 7 deletions macros/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,28 @@ mod variant;
/// `#[ts(optional)]` turns an `t: Option<T>` into `t?: T`, while
/// `#[ts(optional = nullable)]` turns it into `t?: T | null`.
#[derive(Default, Clone, Copy)]
pub struct Optional {
pub optional: bool,
pub nullable: bool,
pub enum Optional {
Optional {
nullable: bool,
},

#[default]
NotOptional,
}

impl Optional {
pub fn or(self, other: Optional) -> Self {
match (self, other) {
(Self::NotOptional, Self::NotOptional) => Self::NotOptional,

(Self::Optional { nullable }, Self::NotOptional)
| (Self::NotOptional, Self::Optional { nullable }) => Self::Optional { nullable },

(Self::Optional { nullable: a }, Self::Optional { nullable: b }) => {
Self::Optional { nullable: a || b }
}
}
}
}

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -202,8 +221,5 @@ fn parse_optional(input: ParseStream) -> Result<Optional> {
false
};

Ok(Optional {
optional: true,
nullable,
})
Ok(Optional::Optional { nullable })
}
5 changes: 1 addition & 4 deletions macros/src/attr/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ impl Attr for StructAttr {
(Some(bound), None) | (None, Some(bound)) => Some(bound),
(None, None) => None,
},
optional: Optional {
optional: self.optional.optional || other.optional.optional,
nullable: self.optional.nullable || other.optional.nullable,
},
optional: self.optional.or(other.optional),
}
}

Expand Down
26 changes: 7 additions & 19 deletions macros/src/types/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,30 +105,18 @@ fn format_field(
let ty = field_attr.type_as(&field.ty);

let opt = match (struct_optional, field_attr.optional) {
(
opt @ Optional { optional: true, .. },
Optional {
optional: false, ..
},
) => opt,
(_, opt @ Optional { optional: true, .. }) => opt,
(
opt @ Optional {
optional: false, ..
},
Optional {
optional: false, ..
},
) => opt,
(opt @ Optional::Optional { .. }, Optional::NotOptional) => opt,
(_, opt @ Optional::Optional { .. }) => opt,
(opt @ Optional::NotOptional, Optional::NotOptional) => opt,
};

let optional_annotation = if opt.optional {
let optional_annotation = if let Optional::Optional { .. } = opt {
quote! { if <#ty as #crate_rename::TS>::IS_OPTION { "?" } else { "" } }
} else {
quote! { "" }
};

let optional_annotation = if field_attr.optional.optional {
let optional_annotation = if let Optional::Optional { .. } = field_attr.optional {
quote! {
if <#ty as #crate_rename::TS>::IS_OPTION {
#optional_annotation
Expand All @@ -153,7 +141,7 @@ fn format_field(
if field_attr.inline {
dependencies.append_from(&ty);

if opt.optional && !opt.nullable {
if let Optional::Optional { nullable: false } = opt {
quote! {
if <#ty as #crate_rename::TS>::IS_OPTION {
<#ty as #crate_rename::TS>::option_inner_inline().unwrap()
Expand All @@ -166,7 +154,7 @@ fn format_field(
}
} else {
dependencies.push(&ty);
if opt.optional && !opt.nullable {
if let Optional::Optional { nullable: false } = opt {
quote! {
if <#ty as #crate_rename::TS>::IS_OPTION {
<#ty as #crate_rename::TS>::option_inner_name().unwrap()
Expand Down

0 comments on commit a562561

Please sign in to comment.