Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for unions in generated service serialization #1414

Merged
merged 15 commits into from
Sep 25, 2023
  •  
  •  
  •  
1 change: 1 addition & 0 deletions services/autorust/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ qstring = "0.7"
[dev-dependencies]
thiserror = "1.0"
crates_io_api = "0.8"
anyhow = "1.0"
46 changes: 45 additions & 1 deletion services/autorust/codegen/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,25 @@ pub struct CodeGen<'a> {
optional_properties: HashSet<PropertyName>,
fix_case_properties: HashSet<&'a str>,
invalid_types: HashSet<PropertyName>,

pub union_types: HashSet<String>,
cataggar marked this conversation as resolved.
Show resolved Hide resolved
}

impl<'a> CodeGen<'a> {
pub fn add_union_type(&mut self, type_name: String) {
self.union_types.insert(type_name);
}

pub fn is_union_type(&self, type_name: &TypeNameCode) -> bool {
self.union_types.contains(&type_name.type_path.to_token_stream().to_string())
}

pub fn set_if_union_type(&self, type_name: &mut TypeNameCode) {
if self.is_union_type(type_name) {
type_name.union(true);
}
}

pub fn new(
crate_config: &'a CrateConfig,
box_properties: HashSet<PropertyName>,
Expand All @@ -47,6 +63,7 @@ impl<'a> CodeGen<'a> {
optional_properties,
fix_case_properties,
invalid_types,
union_types: HashSet::new(),
})
}

Expand Down Expand Up @@ -115,14 +132,15 @@ pub fn parse_query_params(uri: &str) -> Result<HashSet<String>> {
pub struct TypeNameCode {
type_path: TypePath,
force_value: bool,
pub optional: bool,
optional: bool,
vec_count: i32,
impl_into: bool,
allow_impl_into: bool,
boxed: bool,
qualify_models: bool,
allow_qualify_models: bool,
type_name: Option<TypeName>,
union: bool,
}

impl TypeNameCode {
Expand Down Expand Up @@ -180,6 +198,9 @@ impl TypeNameCode {
self.optional = optional;
self
}
pub fn union(&mut self, union: bool) {
self.union = union;
}
pub fn incr_vec_count(mut self) -> Self {
self.vec_count += 1;
self
Expand Down Expand Up @@ -210,6 +231,12 @@ impl TypeNameCode {

fn to_type(&self) -> Type {
let mut tp = self.type_path.clone();
if self.union {
if let Some(last) = tp.path.segments.last_mut() {
last.ident = Ident::new(&format!("{}Union", last.ident), last.ident.span());
}
}

if self.allow_qualify_models && self.qualify_models {
tp.path.segments.insert(0, id_models().into());
}
Expand Down Expand Up @@ -246,6 +273,13 @@ impl TypeNameCode {
}
tp
}

pub fn is_optional(&self) -> bool {
self.optional
}
pub fn is_union(&self) -> bool {
self.union
}
}

impl ToString for TypeNameCode {
Expand Down Expand Up @@ -291,6 +325,7 @@ impl From<TypePath> for TypeNameCode {
qualify_models: false,
allow_qualify_models: false,
type_name: None,
union: false,
}
}
}
Expand Down Expand Up @@ -406,6 +441,7 @@ fn tp_date_time() -> TypePath {
#[cfg(test)]
mod tests {
use super::*;
use anyhow::ensure;

#[test]
fn test_parse_query_params() -> Result<()> {
Expand Down Expand Up @@ -503,4 +539,12 @@ mod tests {
assert_eq!("bytes :: Bytes", tp.to_string());
Ok(())
}

#[test]
fn test_with_union() -> anyhow::Result<()> {
let mut tp = TypeNameCode::try_from("farm::Animal")?;
tp.union(true);
ensure!("farm :: AnimalUnion" == tp.to_string());
cataggar marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}
}
Loading
Loading