From 1c01047ad274a393b4d52e4970c906048617bc6f Mon Sep 17 00:00:00 2001 From: Andrzej Ressel <github@andrzejressel.pl> Date: Sun, 15 Dec 2024 16:23:02 +0100 Subject: [PATCH] Enum --- examples/typesystem/src/lib.rs | 37 ++++-- .../src/types/builder_version.rs | 11 ++ .../src/types/cache_from.rs | 2 + .../src/types/docker_build.rs | 2 + .../src/types/mod.rs | 3 +- .../src/types/registry.rs | 2 + .../src/resource/typesystem_server.rs | 6 +- .../src/types/mod.rs | 10 +- .../src/types/my_enum.rs | 6 + .../types/{enum_case_1.rs => union_case_1.rs} | 2 +- .../types/{enum_case_2.rs => union_case_2.rs} | 2 +- providers/typesystem.json | 28 ++-- .../src/code_generation/yaml/model.rs | 3 +- pulumi_wasm_generator_lib/src/model.rs | 10 +- .../src/output/rust/source_code_types_code.rs | 98 ++++++++++---- .../src/output/rust/source_code_types_mod.rs | 8 +- .../src/output/rust/types_code.rs.handlebars | 4 + .../output/rust/types_code_enum.rs.handlebars | 16 +++ pulumi_wasm_generator_lib/src/schema.rs | 120 +++++++++++------- .../lib/src/types/ignore_tags.rs | 2 + .../mini-awsnative/lib/src/types/mod.rs | 3 +- .../mini-awsnative/lib/src/types/region.rs | 80 ++++++++++++ pulumi_wasm_generator_lib/tests/test.rs | 4 +- 23 files changed, 357 insertions(+), 102 deletions(-) create mode 100644 providers/pulumi_wasm_provider_docker_rust/src/types/builder_version.rs create mode 100644 providers/pulumi_wasm_provider_typesystem_rust/src/types/my_enum.rs rename providers/pulumi_wasm_provider_typesystem_rust/src/types/{enum_case_1.rs => union_case_1.rs} (89%) rename providers/pulumi_wasm_provider_typesystem_rust/src/types/{enum_case_2.rs => union_case_2.rs} (89%) create mode 100644 pulumi_wasm_generator_lib/src/output/rust/types_code_enum.rs.handlebars create mode 100644 pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/region.rs diff --git a/examples/typesystem/src/lib.rs b/examples/typesystem/src/lib.rs index 28c752ca4..6bc262088 100644 --- a/examples/typesystem/src/lib.rs +++ b/examples/typesystem/src/lib.rs @@ -3,7 +3,7 @@ mod tests { use pulumi_wasm_provider_common::OneOf2; use pulumi_wasm_rust::Output; use pulumi_wasm_typesystem::typesystem_server::TypesystemServerArgs; - use pulumi_wasm_typesystem::{EnumCase1, EnumCase2}; + use pulumi_wasm_typesystem::{MyEnum, UnionCase1, UnionCase2}; use std::panic::catch_unwind; #[test] @@ -12,11 +12,11 @@ mod tests { } #[test] - fn test_deserialization() { - let case1 = EnumCase1::builder() + fn test_case_deserialization() { + let case1 = UnionCase1::builder() .field_1("value1".to_string()) .build_struct(); - let case2 = EnumCase2::builder() + let case2 = UnionCase2::builder() .field_2("value2".to_string()) .build_struct(); @@ -25,13 +25,28 @@ mod tests { assert_eq!(case1_json, r#"{"field1":"value1"}"#); assert_eq!(case2_json, r#"{"field2":"value2"}"#); - let deserialized_case1: EnumCase1 = serde_json::from_str(&case1_json).unwrap(); + let deserialized_case1: UnionCase1 = serde_json::from_str(&case1_json).unwrap(); + let deserialized_case2: UnionCase2 = serde_json::from_str(&case2_json).unwrap(); assert_eq!(deserialized_case1, case1); - - let deserialized_case2: EnumCase2 = serde_json::from_str(&case2_json).unwrap(); assert_eq!(deserialized_case2, case2); } + #[test] + fn test_enum_deserialization() { + let enum1 = MyEnum::Value1; + let enum2 = MyEnum::Value2; + + let enum1_json = serde_json::to_string(&enum1).unwrap(); + let enum2_json = serde_json::to_string(&enum2).unwrap(); + assert_eq!(enum1_json, r#""VALUE1""#); + assert_eq!(enum2_json, r#""Value2""#); + + let deserialized_enum1: MyEnum = serde_json::from_str(&enum1_json).unwrap(); + let deserialized_enum2: MyEnum = serde_json::from_str(&enum2_json).unwrap(); + assert_eq!(deserialized_enum1, enum1); + assert_eq!(deserialized_enum2, enum2); + } + fn compilation_test() { // String let output = Output::new(&"Hello, World!".to_string()); @@ -67,10 +82,10 @@ mod tests { // let _ = TypesystemServerArgs::builder().optional_string_array([string_output]); // Union - let case1 = EnumCase1::builder() + let case1 = UnionCase1::builder() .field_1("value1".to_string()) .build_struct(); - let case2 = EnumCase2::builder() + let case2 = UnionCase2::builder() .field_2("value2".to_string()) .build_struct(); let enum_case1_output = Output::new(&case1); @@ -81,10 +96,10 @@ mod tests { let _ = TypesystemServerArgs::builder().required_union(enum_case2_output.map(OneOf2::right)); - let case1 = EnumCase1::builder() + let case1 = UnionCase1::builder() .field_1("value1".to_string()) .build_struct(); - let case2 = EnumCase2::builder() + let case2 = UnionCase2::builder() .field_2("value2".to_string()) .build_struct(); let _ = TypesystemServerArgs::builder().optional_union(OneOf2::left(case1)); diff --git a/providers/pulumi_wasm_provider_docker_rust/src/types/builder_version.rs b/providers/pulumi_wasm_provider_docker_rust/src/types/builder_version.rs new file mode 100644 index 000000000..4f33d1191 --- /dev/null +++ b/providers/pulumi_wasm_provider_docker_rust/src/types/builder_version.rs @@ -0,0 +1,11 @@ +//! The version of the Docker builder. + +#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)] +pub enum BuilderVersion { + /// The first generation builder for Docker Daemon + #[serde(rename = "BuilderV1")] + BuilderV1, + /// The builder based on moby/buildkit project + #[serde(rename = "BuilderBuildKit")] + BuilderBuildKit, +} diff --git a/providers/pulumi_wasm_provider_docker_rust/src/types/cache_from.rs b/providers/pulumi_wasm_provider_docker_rust/src/types/cache_from.rs index 1651bc7d7..9c4ceccfc 100644 --- a/providers/pulumi_wasm_provider_docker_rust/src/types/cache_from.rs +++ b/providers/pulumi_wasm_provider_docker_rust/src/types/cache_from.rs @@ -1,3 +1,5 @@ +//! Contains a list of images to reference when building using a cache + #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] pub struct CacheFrom { diff --git a/providers/pulumi_wasm_provider_docker_rust/src/types/docker_build.rs b/providers/pulumi_wasm_provider_docker_rust/src/types/docker_build.rs index 100325201..3eee7b44e 100644 --- a/providers/pulumi_wasm_provider_docker_rust/src/types/docker_build.rs +++ b/providers/pulumi_wasm_provider_docker_rust/src/types/docker_build.rs @@ -1,3 +1,5 @@ +//! The Docker build context + #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] pub struct DockerBuild { diff --git a/providers/pulumi_wasm_provider_docker_rust/src/types/mod.rs b/providers/pulumi_wasm_provider_docker_rust/src/types/mod.rs index 3d8bdcb49..de0341fb6 100644 --- a/providers/pulumi_wasm_provider_docker_rust/src/types/mod.rs +++ b/providers/pulumi_wasm_provider_docker_rust/src/types/mod.rs @@ -1,3 +1,5 @@ +mod builder_version; +pub use builder_version::*; mod cache_from; pub use cache_from::*; mod container_capabilities; @@ -127,4 +129,3 @@ pub use get_network_ipam_config::*; mod registry_auth; pub use registry_auth::*; -pub type BuilderVersion = String; diff --git a/providers/pulumi_wasm_provider_docker_rust/src/types/registry.rs b/providers/pulumi_wasm_provider_docker_rust/src/types/registry.rs index c53b46b29..447e5014c 100644 --- a/providers/pulumi_wasm_provider_docker_rust/src/types/registry.rs +++ b/providers/pulumi_wasm_provider_docker_rust/src/types/registry.rs @@ -1,3 +1,5 @@ +//! Describes a Docker container registry + #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] pub struct Registry { diff --git a/providers/pulumi_wasm_provider_typesystem_rust/src/resource/typesystem_server.rs b/providers/pulumi_wasm_provider_typesystem_rust/src/resource/typesystem_server.rs index 7b2ae0037..5ceb1065d 100644 --- a/providers/pulumi_wasm_provider_typesystem_rust/src/resource/typesystem_server.rs +++ b/providers/pulumi_wasm_provider_typesystem_rust/src/resource/typesystem_server.rs @@ -7,15 +7,15 @@ pub struct TypesystemServerArgs { #[builder(into, default = ::pulumi_wasm_rust::Output::empty())] pub optional_string_input: pulumi_wasm_rust::Output<Option<String>>, #[builder(into, default = ::pulumi_wasm_rust::Output::empty())] - pub optional_union: pulumi_wasm_rust::Output<Option<pulumi_wasm_provider_common::OneOf2<crate::types::EnumCase1, crate::types::EnumCase2>>>, + pub optional_union: pulumi_wasm_rust::Output<Option<pulumi_wasm_provider_common::OneOf2<crate::types::UnionCase1, crate::types::UnionCase2>>>, #[builder(into, default = ::pulumi_wasm_rust::Output::empty())] - pub properties_collection: pulumi_wasm_rust::Output<Option<Vec<pulumi_wasm_provider_common::OneOf2<crate::types::EnumCase1, crate::types::EnumCase2>>>>, + pub properties_collection: pulumi_wasm_rust::Output<Option<Vec<pulumi_wasm_provider_common::OneOf2<crate::types::UnionCase1, crate::types::UnionCase2>>>>, #[builder(into)] pub required_string_array: pulumi_wasm_rust::Output<Vec<String>>, #[builder(into)] pub required_string_input: pulumi_wasm_rust::Output<String>, #[builder(into)] - pub required_union: pulumi_wasm_rust::Output<pulumi_wasm_provider_common::OneOf2<crate::types::EnumCase1, crate::types::EnumCase2>>, + pub required_union: pulumi_wasm_rust::Output<pulumi_wasm_provider_common::OneOf2<crate::types::UnionCase1, crate::types::UnionCase2>>, } pub struct TypesystemServerResult { diff --git a/providers/pulumi_wasm_provider_typesystem_rust/src/types/mod.rs b/providers/pulumi_wasm_provider_typesystem_rust/src/types/mod.rs index cce8fed51..265512f4c 100644 --- a/providers/pulumi_wasm_provider_typesystem_rust/src/types/mod.rs +++ b/providers/pulumi_wasm_provider_typesystem_rust/src/types/mod.rs @@ -1,5 +1,7 @@ -mod enum_case_1; -pub use enum_case_1::*; -mod enum_case_2; -pub use enum_case_2::*; +mod my_enum; +pub use my_enum::*; +mod union_case_1; +pub use union_case_1::*; +mod union_case_2; +pub use union_case_2::*; diff --git a/providers/pulumi_wasm_provider_typesystem_rust/src/types/my_enum.rs b/providers/pulumi_wasm_provider_typesystem_rust/src/types/my_enum.rs new file mode 100644 index 000000000..bb11851f4 --- /dev/null +++ b/providers/pulumi_wasm_provider_typesystem_rust/src/types/my_enum.rs @@ -0,0 +1,6 @@ +#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)] +pub enum MyEnum { + #[serde(rename = "VALUE1")] + Value1, + Value2, +} diff --git a/providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_1.rs b/providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_1.rs similarity index 89% rename from providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_1.rs rename to providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_1.rs index 72513d167..6577f484d 100644 --- a/providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_1.rs +++ b/providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_1.rs @@ -1,6 +1,6 @@ #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] -pub struct EnumCase1 { +pub struct UnionCase1 { #[builder(into)] #[serde(rename = "field1")] pub r#field_1: Box<String>, diff --git a/providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_2.rs b/providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_2.rs similarity index 89% rename from providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_2.rs rename to providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_2.rs index e58d2fe78..b24e8a1b0 100644 --- a/providers/pulumi_wasm_provider_typesystem_rust/src/types/enum_case_2.rs +++ b/providers/pulumi_wasm_provider_typesystem_rust/src/types/union_case_2.rs @@ -1,6 +1,6 @@ #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] -pub struct EnumCase2 { +pub struct UnionCase2 { #[builder(into)] #[serde(rename = "field2")] pub r#field_2: Box<String>, diff --git a/providers/typesystem.json b/providers/typesystem.json index 62798835d..0a53c859d 100644 --- a/providers/typesystem.json +++ b/providers/typesystem.json @@ -26,11 +26,11 @@ "oneOf": [ { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase1" + "$ref": "#/types/typesystem:index:UnionCase1" }, { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase2" + "$ref": "#/types/typesystem:index:UnionCase2" } ] }, @@ -38,11 +38,11 @@ "oneOf": [ { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase1" + "$ref": "#/types/typesystem:index:UnionCase1" }, { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase2" + "$ref": "#/types/typesystem:index:UnionCase2" } ] }, @@ -52,11 +52,11 @@ "oneOf": [ { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase1" + "$ref": "#/types/typesystem:index:UnionCase1" }, { "type": "object", - "$ref": "#/types/typesystem:index:EnumCase2" + "$ref": "#/types/typesystem:index:UnionCase2" } ] } @@ -71,7 +71,7 @@ } }, "types": { - "typesystem:index:EnumCase1": { + "typesystem:index:UnionCase1": { "type": "object", "properties": { "field1": { @@ -82,7 +82,7 @@ "field1" ] }, - "typesystem:index:EnumCase2": { + "typesystem:index:UnionCase2": { "type": "object", "properties": { "field2": { @@ -92,6 +92,18 @@ "required": [ "field2" ] + }, + "typesystem:index:MyEnum": { + "type": "string", + "enum": [ + { + "name": "Value1", + "value": "VALUE1" + }, + { + "name": "Value2" + } + ] } }, "language": { diff --git a/pulumi_wasm_generator_lib/src/code_generation/yaml/model.rs b/pulumi_wasm_generator_lib/src/code_generation/yaml/model.rs index 7f670d5ad..4ed3c1478 100644 --- a/pulumi_wasm_generator_lib/src/code_generation/yaml/model.rs +++ b/pulumi_wasm_generator_lib/src/code_generation/yaml/model.rs @@ -251,7 +251,8 @@ fn map_type( let tpe = &context.package.types[element_id]; let gtp = match tpe { - GlobalType::Object(gtp) => gtp, + GlobalType::Object(_, gtp) => gtp, + GlobalType::StringEnum(_, _) => panic!("StringEnum type is not supported"), GlobalType::String => panic!("String type is not supported"), GlobalType::Boolean => panic!("Boolean type is not supported"), GlobalType::Number => panic!("Number type is not supported"), diff --git a/pulumi_wasm_generator_lib/src/model.rs b/pulumi_wasm_generator_lib/src/model.rs index dac81da9d..977980f32 100644 --- a/pulumi_wasm_generator_lib/src/model.rs +++ b/pulumi_wasm_generator_lib/src/model.rs @@ -108,13 +108,21 @@ pub(crate) struct GlobalTypeProperty { #[derive(Debug, PartialEq, Hash, Ord, PartialOrd, Eq)] pub(crate) enum GlobalType { - Object(Vec<GlobalTypeProperty>), + Object(Option<String>, Vec<GlobalTypeProperty>), + StringEnum(Option<String>, Vec<StringEnumElement>), String, Boolean, Number, Integer, } +#[derive(Debug, PartialEq, Hash, Ord, PartialOrd, Eq)] +pub(crate) struct StringEnumElement { + pub(crate) name: String, + pub(crate) value: Option<String>, + pub(crate) description: Option<String>, +} + #[derive(Debug, PartialEq, Hash, Ord, PartialOrd, Eq)] pub(crate) struct Resource { pub(crate) element_id: ElementId, diff --git a/pulumi_wasm_generator_lib/src/output/rust/source_code_types_code.rs b/pulumi_wasm_generator_lib/src/output/rust/source_code_types_code.rs index f3767d514..044b58855 100644 --- a/pulumi_wasm_generator_lib/src/output/rust/source_code_types_code.rs +++ b/pulumi_wasm_generator_lib/src/output/rust/source_code_types_code.rs @@ -7,6 +7,7 @@ use std::collections::HashMap; use std::path::PathBuf; static TEMPLATE: &str = include_str!("types_code.rs.handlebars"); +static ENUM_TEMPLATE: &str = include_str!("types_code_enum.rs.handlebars"); #[derive(Serialize)] struct Property { @@ -21,10 +22,26 @@ struct Property { struct RefType { // name: String, fields: Vec<Property>, + description_lines: Vec<String>, struct_name: String, file_name: String, } +#[derive(Serialize)] +struct Enum { + struct_name: String, + file_name: String, + description_lines: Vec<String>, + values: Vec<EnumValue>, +} + +#[derive(Serialize)] +struct EnumValue { + name: String, + description_lines: Vec<String>, + value: Option<String>, +} + #[derive(Serialize)] struct AliasType { name: String, @@ -35,21 +52,22 @@ struct AliasType { struct Package { name: String, types: Vec<RefType>, - aliases: Vec<AliasType>, + enums: Vec<Enum>, } fn convert_model(package: &crate::model::Package) -> Package { let mut real_types = Vec::new(); - let mut aliases = Vec::new(); + let mut enums = Vec::new(); package .types .iter() .for_each(|(element_id, resource)| match resource { - GlobalType::Object(properties) => { + GlobalType::Object(description, properties) => { let ref_type = RefType { struct_name: element_id.get_rust_struct_name(), file_name: element_id.get_rust_struct_name().to_case(Case::Snake), + description_lines: crate::utils::to_lines(description.clone(), package, None), fields: properties .iter() .map(|global_type_property| Property { @@ -71,28 +89,36 @@ fn convert_model(package: &crate::model::Package) -> Package { }; real_types.push(ref_type); } - GlobalType::String => aliases.push(AliasType { - name: element_id.name.to_string(), - type_: "String".to_string(), - }), - GlobalType::Boolean => aliases.push(AliasType { - name: element_id.name.to_string(), - type_: "bool".to_string(), - }), - GlobalType::Number => aliases.push(AliasType { - name: element_id.name.to_string(), - type_: "f64".to_string(), - }), - GlobalType::Integer => aliases.push(AliasType { - name: element_id.name.to_string(), - type_: "i32".to_string(), - }), + GlobalType::StringEnum(description, enum_values) => { + let enum_type = Enum { + struct_name: element_id.get_rust_struct_name(), + file_name: element_id.get_rust_struct_name().to_case(Case::Snake), + description_lines: crate::utils::to_lines(description.clone(), package, None), + values: enum_values + .iter() + .map(|enum_value| EnumValue { + name: enum_value.name.clone(), + value: enum_value.value.clone(), + description_lines: crate::utils::to_lines( + enum_value.description.clone(), + package, + None, + ), + }) + .collect(), + }; + enums.push(enum_type); + } + GlobalType::String => {} + GlobalType::Boolean => {} + GlobalType::Number => {} + GlobalType::Integer => {} }); Package { name: package.name.clone(), types: real_types, - aliases, + enums, } } @@ -100,17 +126,43 @@ pub(crate) fn generate_source_code(package: &crate::model::Package) -> HashMap<P let handlebars = Handlebars::new(); let package = convert_model(package); - package + let types: HashMap<_, _> = package .types .iter() .map(|type_| { let rendered_file = handlebars .render_template(TEMPLATE, &json!({"type": type_})) - .unwrap(); + .unwrap() + .trim_start() + .to_string(); //FIXME ( PathBuf::from(format!("{}.rs", type_.file_name)), rendered_file, ) }) - .collect() + .collect(); + + let enums: HashMap<_, _> = package + .enums + .iter() + .map(|enum_| { + let rendered_file = handlebars + .render_template(ENUM_TEMPLATE, &json!({"enum": enum_})) + .unwrap() + .trim_start() + .to_string(); //FIXME + ( + PathBuf::from(format!("{}.rs", enum_.file_name)), + rendered_file, + ) + }) + .collect(); + + let mut result = HashMap::new(); + result.extend(types); + result.extend(enums); + + result + + // let enums = } diff --git a/pulumi_wasm_generator_lib/src/output/rust/source_code_types_mod.rs b/pulumi_wasm_generator_lib/src/output/rust/source_code_types_mod.rs index 6638a31d6..0f8cf114c 100644 --- a/pulumi_wasm_generator_lib/src/output/rust/source_code_types_mod.rs +++ b/pulumi_wasm_generator_lib/src/output/rust/source_code_types_mod.rs @@ -31,7 +31,13 @@ fn convert_model(package: &crate::model::Package) -> Package { .types .iter() .for_each(|(element_id, resource)| match resource { - GlobalType::Object(_properties) => { + GlobalType::Object(_, _) => { + let ref_type = RefType { + file_name: element_id.get_rust_struct_name().to_case(Case::Snake), + }; + real_types.push(ref_type); + } + GlobalType::StringEnum(_, _) => { let ref_type = RefType { file_name: element_id.get_rust_struct_name().to_case(Case::Snake), }; diff --git a/pulumi_wasm_generator_lib/src/output/rust/types_code.rs.handlebars b/pulumi_wasm_generator_lib/src/output/rust/types_code.rs.handlebars index 5c8e96930..cb969be55 100644 --- a/pulumi_wasm_generator_lib/src/output/rust/types_code.rs.handlebars +++ b/pulumi_wasm_generator_lib/src/output/rust/types_code.rs.handlebars @@ -1,3 +1,7 @@ +{{#each type.description_lines}} + //! {{&this}} +{{/each}} + #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] pub struct {{type.struct_name}} { diff --git a/pulumi_wasm_generator_lib/src/output/rust/types_code_enum.rs.handlebars b/pulumi_wasm_generator_lib/src/output/rust/types_code_enum.rs.handlebars new file mode 100644 index 000000000..690c8381a --- /dev/null +++ b/pulumi_wasm_generator_lib/src/output/rust/types_code_enum.rs.handlebars @@ -0,0 +1,16 @@ +{{#each enum.description_lines}} + //! {{&this}} +{{/each}} + +#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)] +pub enum {{enum.struct_name}} { + {{#each enum.values as |value|}} + {{#each value.description_lines}} + /// {{&this}} + {{/each}} + {{#if value.value}} + #[serde(rename = "{{value.value}}")] + {{/if}} + {{value.name}}, + {{/each}} +} diff --git a/pulumi_wasm_generator_lib/src/schema.rs b/pulumi_wasm_generator_lib/src/schema.rs index c455af11d..3af951260 100644 --- a/pulumi_wasm_generator_lib/src/schema.rs +++ b/pulumi_wasm_generator_lib/src/schema.rs @@ -1,4 +1,7 @@ -use crate::model::{ElementId, GlobalType, GlobalTypeProperty, InputProperty, OutputProperty, Ref}; +use crate::model::{ + ElementId, GlobalType, GlobalTypeProperty, InputProperty, OutputProperty, Ref, + StringEnumElement, +}; use anyhow::{anyhow, Context, Result}; use serde::Deserialize; use std::collections::{BTreeMap, BTreeSet, HashSet}; @@ -55,6 +58,8 @@ struct ObjectType { properties: PulumiMap<Property>, #[serde(default)] required: BTreeSet<String>, + #[serde(rename = "enum")] + enum_: Option<Vec<EnumValue>>, } #[derive(Deserialize, Debug)] @@ -69,17 +74,15 @@ struct Resource { #[derive(Deserialize, Debug)] struct EnumValue { - name: Option<String>, + name: String, description: Option<String>, - // value: Option<String>, //apparently any + value: Option<String>, } #[derive(Deserialize, Debug)] struct ComplexType { #[serde(flatten)] object_type: ObjectType, - #[serde(default)] - r#enum: Vec<EnumValue>, } #[derive(Deserialize, Debug)] @@ -305,45 +308,7 @@ pub(crate) fn to_model(package: &Package) -> Result<crate::model::Package> { .iter() .map(|(type_name, type_)| { //TODO: Enums, support non objects - let element_id = ElementId::new(type_name)?; - let tpe = match type_.object_type { - ObjectType { r#type: None, .. } => Err(anyhow!("Unknown complex type")), - ObjectType { - r#type: Some(TypeEnum::Object), - .. - } => Ok(GlobalType::Object( - convert_output_property_object_type(&element_id, &type_.object_type)? - .iter() - .map(|p| GlobalTypeProperty { - name: p.name.clone(), - r#type: p.r#type.clone(), - description: p.description.clone(), - }) - .collect(), - )), - ObjectType { - r#type: Some(TypeEnum::Array), - .. - } => Err(anyhow!("Array not supported")), - ObjectType { - r#type: Some(TypeEnum::Boolean), - .. - } => Ok(GlobalType::Boolean), - ObjectType { - r#type: Some(TypeEnum::Integer), - .. - } => Ok(GlobalType::Integer), - ObjectType { - r#type: Some(TypeEnum::Number), - .. - } => Ok(GlobalType::Number), - ObjectType { - r#type: Some(TypeEnum::String), - .. - } => Ok(GlobalType::String), - } - .context(format!("Cannot convert type [{type_name}]"))?; - Ok((element_id, tpe)) + convert_to_global_type(type_name, &type_) }) .collect::<Result<BTreeMap<_, _>>>() .context("Cannot handle types")?; @@ -357,6 +322,73 @@ pub(crate) fn to_model(package: &Package) -> Result<crate::model::Package> { }) } +fn convert_to_global_type( + type_name: &String, + type_: &&ComplexType, +) -> Result<(ElementId, GlobalType)> { + let element_id = ElementId::new(type_name)?; + println!("Converting type: {:?}", type_); + let tpe = match &type_.object_type { + ObjectType { r#type: None, .. } => Err(anyhow!("Unknown complex type")), + ObjectType { + r#type: Some(TypeEnum::Object), + .. + } => Ok(GlobalType::Object( + type_.object_type.description.clone(), + convert_output_property_object_type(&element_id, &type_.object_type)? + .iter() + .map(|p| GlobalTypeProperty { + name: p.name.clone(), + r#type: p.r#type.clone(), + description: p.description.clone(), + }) + .collect(), + )), + ObjectType { + r#type: Some(TypeEnum::Array), + .. + } => Err(anyhow!("Array not supported")), + ObjectType { + r#type: Some(TypeEnum::Boolean), + .. + } => Ok(GlobalType::Boolean), + ObjectType { + r#type: Some(TypeEnum::Integer), + .. + } => Ok(GlobalType::Integer), + ObjectType { + r#type: Some(TypeEnum::Number), + .. + } => Ok(GlobalType::Number), + ObjectType { + r#type: Some(TypeEnum::String), + enum_: Some(enum_cases), + description, + .. + } => Ok(create_string_enum(description, enum_cases)), + ObjectType { + r#type: Some(TypeEnum::String), + .. + } => Ok(GlobalType::String), + } + .context(format!("Cannot convert type [{type_name}]"))?; + Ok((element_id, tpe)) +} + +fn create_string_enum(description: &Option<String>, enum_values: &[EnumValue]) -> GlobalType { + GlobalType::StringEnum( + description.clone(), + enum_values + .iter() + .map(|enum_value| StringEnumElement { + name: enum_value.name.clone(), + value: enum_value.value.clone(), + description: enum_value.description.clone(), + }) + .collect(), + ) +} + fn invalid_required_complextype_required_fields() -> HashSet<(ElementId, String)> { HashSet::from([ // https://github.com/pulumi/pulumi-docker/issues/1052 diff --git a/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/ignore_tags.rs b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/ignore_tags.rs index f050aff79..49246def4 100644 --- a/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/ignore_tags.rs +++ b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/ignore_tags.rs @@ -1,3 +1,5 @@ +//! The configuration with resource tag settings to ignore across all resources handled by this provider (except any individual service tag resources such as `ec2.Tag`) for situations where external systems are managing certain resource tags. + #[derive(serde::Deserialize, serde::Serialize, bon::Builder, Debug, PartialEq, Clone)] #[builder(finish_fn = build_struct)] pub struct IgnoreTags { diff --git a/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/mod.rs b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/mod.rs index 01b9af633..ec4b65b8b 100644 --- a/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/mod.rs +++ b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/mod.rs @@ -1,4 +1,5 @@ +mod region; +pub use region::*; mod ignore_tags; pub use ignore_tags::*; -pub type Region = String; diff --git a/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/region.rs b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/region.rs new file mode 100644 index 000000000..5a617bd0a --- /dev/null +++ b/pulumi_wasm_generator_lib/tests/output/mini-awsnative/lib/src/types/region.rs @@ -0,0 +1,80 @@ +//! A Region represents any valid Amazon region that may be targeted with deployments. + +#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Clone)] +pub enum Region { + /// Africa (Cape Town) + #[serde(rename = "af-south-1")] + AFSouth1, + /// Asia Pacific (Hong Kong) + #[serde(rename = "ap-east-1")] + APEast1, + /// Asia Pacific (Tokyo) + #[serde(rename = "ap-northeast-1")] + APNortheast1, + /// Asia Pacific (Seoul) + #[serde(rename = "ap-northeast-2")] + APNortheast2, + /// Asia Pacific (Osaka) + #[serde(rename = "ap-northeast-3")] + APNortheast3, + /// Asia Pacific (Mumbai) + #[serde(rename = "ap-south-1")] + APSouth1, + /// Asia Pacific (Singapore) + #[serde(rename = "ap-southeast-1")] + APSoutheast1, + /// Asia Pacific (Sydney) + #[serde(rename = "ap-southeast-2")] + APSoutheast2, + /// Canada (Central) + #[serde(rename = "ca-central-1")] + CACentral, + /// China (Beijing) + #[serde(rename = "cn-north-1")] + CNNorth1, + /// China (Ningxia) + #[serde(rename = "cn-northwest-1")] + CNNorthwest1, + /// Europe (Frankfurt) + #[serde(rename = "eu-central-1")] + EUCentral1, + /// Europe (Stockholm) + #[serde(rename = "eu-north-1")] + EUNorth1, + /// Europe (Ireland) + #[serde(rename = "eu-west-1")] + EUWest1, + /// Europe (London) + #[serde(rename = "eu-west-2")] + EUWest2, + /// Europe (Paris) + #[serde(rename = "eu-west-3")] + EUWest3, + /// Europe (Milan) + #[serde(rename = "eu-south-1")] + EUSouth1, + /// Middle East (Bahrain) + #[serde(rename = "me-south-1")] + MESouth1, + /// South America (São Paulo) + #[serde(rename = "sa-east-1")] + SAEast1, + /// AWS GovCloud (US-East) + #[serde(rename = "us-gov-east-1")] + USGovEast1, + /// AWS GovCloud (US-West) + #[serde(rename = "us-gov-west-1")] + USGovWest1, + /// US East (N. Virginia) + #[serde(rename = "us-east-1")] + USEast1, + /// US East (Ohio) + #[serde(rename = "us-east-2")] + USEast2, + /// US West (N. California) + #[serde(rename = "us-west-1")] + USWest1, + /// US West (Oregon) + #[serde(rename = "us-west-2")] + USWest2, +} diff --git a/pulumi_wasm_generator_lib/tests/test.rs b/pulumi_wasm_generator_lib/tests/test.rs index 5ba39597b..5468ce981 100644 --- a/pulumi_wasm_generator_lib/tests/test.rs +++ b/pulumi_wasm_generator_lib/tests/test.rs @@ -22,14 +22,14 @@ fn functions_secrets() -> Result<()> { } #[test] -// https://github.com/andrzejressel/pulumi-wasm/issues/394 +// https://github.com/andrzejressel/pulumi-wasm/issues/564 #[ignore] fn output_funcs() -> Result<()> { run_pulumi_generator_test("output-funcs", "mypkg") } #[test] -// https://github.com/andrzejressel/pulumi-wasm/issues/394 +// https://github.com/andrzejressel/pulumi-wasm/issues/563 #[ignore] fn output_funcs_edgeorder() -> Result<()> { run_pulumi_generator_test("output-funcs-edgeorder", "myedgeorder")