diff --git a/crates/dagger-codegen/src/lib.rs b/crates/dagger-codegen/src/lib.rs index 8e4ca7b..4ca63cd 100644 --- a/crates/dagger-codegen/src/lib.rs +++ b/crates/dagger-codegen/src/lib.rs @@ -8,6 +8,18 @@ use dagger_core::introspection::Schema; use self::generator::DynGenerator; +fn set_schema_parents(mut schema: Schema) -> Schema { + for t in schema.types.as_mut().into_iter().flatten().flatten() { + let t_parent = t.full_type.clone(); + for mut field in t.full_type.fields.as_mut().into_iter().flatten() { + field.parent_type = Some(t_parent.clone()); + } + } + + return schema; +} + pub fn generate(schema: Schema, generator: DynGenerator) -> eyre::Result { + let schema = set_schema_parents(schema); generator.generate(schema) } diff --git a/crates/dagger-codegen/src/rust/functions.rs b/crates/dagger-codegen/src/rust/functions.rs index 2daa519..4728cf2 100644 --- a/crates/dagger-codegen/src/rust/functions.rs +++ b/crates/dagger-codegen/src/rust/functions.rs @@ -1,5 +1,16 @@ use convert_case::{Case, Casing}; +use dagger_core::introspection::FullTypeFields; pub fn format_name(s: &str) -> String { s.to_case(Case::Pascal) } + +pub fn field_options_struct_name(field: &FullTypeFields) -> Option { + field + .parent_type + .as_ref() + .map(|p| p.name.as_ref()) + .flatten() + .zip(field.name.as_ref()) + .map(|(parent_name, field_name)| format!("{parent_name}{field_name}Opts")) +} diff --git a/crates/dagger-codegen/src/rust/mod.rs b/crates/dagger-codegen/src/rust/mod.rs index eb6717c..46ef19f 100644 --- a/crates/dagger-codegen/src/rust/mod.rs +++ b/crates/dagger-codegen/src/rust/mod.rs @@ -23,7 +23,7 @@ pub struct RustGenerator {} impl Generator for RustGenerator { fn generate(&self, schema: Schema) -> eyre::Result { let render = Arc::new(Mutex::new(rust::Tokens::new())); - let common_funcs = CommonFunctions::new(Arc::new(FormatTypeFunc {})); + let common_funcs = Arc::new(CommonFunctions::new(Arc::new(FormatTypeFunc {}))); println!("generating dagger for rust"); let visitor = Visitor { @@ -31,6 +31,8 @@ impl Generator for RustGenerator { handlers: VisitHandlers { visit_scalar: Arc::new({ let render = render.clone(); + let common_funcs = common_funcs.clone(); + move |t| { println!("generating scalar"); let rendered_scalar = render_scalar(t)?; @@ -47,10 +49,11 @@ impl Generator for RustGenerator { }), visit_object: Arc::new({ let render = render.clone(); + let common_funcs = common_funcs.clone(); move |t| { println!("generating object"); - let rendered_scalar = render_object(t)?; + let rendered_scalar = render_object(&common_funcs, t)?; let mut render = render.lock().unwrap(); @@ -63,6 +66,7 @@ impl Generator for RustGenerator { }), visit_input: Arc::new({ let render = render.clone(); + let common_funcs = common_funcs.clone(); move |t| { println!("generating input"); @@ -79,6 +83,7 @@ impl Generator for RustGenerator { }), visit_enum: Arc::new({ let render = render.clone(); + let common_funcs = common_funcs.clone(); move |t| { println!("generating enum"); diff --git a/crates/dagger-codegen/src/rust/templates/object_tmpl.rs b/crates/dagger-codegen/src/rust/templates/object_tmpl.rs index 8653c78..c7c5919 100644 --- a/crates/dagger-codegen/src/rust/templates/object_tmpl.rs +++ b/crates/dagger-codegen/src/rust/templates/object_tmpl.rs @@ -2,16 +2,17 @@ use dagger_core::introspection::{FullType, FullTypeFields}; use genco::prelude::rust; use genco::quote; -use crate::rust::functions::format_name; +use crate::functions::CommonFunctions; +use crate::rust::functions::{field_options_struct_name, format_name}; use crate::utility::OptionExt; -pub fn render_object(t: &FullType) -> eyre::Result { +pub fn render_object(funcs: &CommonFunctions, t: &FullType) -> eyre::Result { Ok(quote! { pub struct $(t.name.pipe(|s| format_name(s))) { } - $(t.fields.pipe(render_optional_args)) + $(t.fields.pipe(|f| render_optional_args(funcs, f))) impl $(t.name.pipe(|s| format_name(s))) { @@ -19,10 +20,13 @@ pub fn render_object(t: &FullType) -> eyre::Result { }) } -fn render_optional_args(fields: &Vec) -> Option { +fn render_optional_args( + funcs: &CommonFunctions, + fields: &Vec, +) -> Option { let rendered_fields = fields .iter() - .map(render_optional_arg) + .map(|f| render_optional_arg(funcs, f)) .flatten() .collect::>(); @@ -35,6 +39,13 @@ fn render_optional_args(fields: &Vec) -> Option { } } -fn render_optional_arg(field: &FullTypeFields) -> Option { - todo!() +fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Option { + field + .type_ + .pipe(|t| funcs.format_output_type(&t.type_ref)) + .pipe(|f| { + quote! { + $f + } + }) } diff --git a/crates/dagger-core/src/introspection.rs b/crates/dagger-core/src/introspection.rs index 3ae0d03..87a93ad 100644 --- a/crates/dagger-core/src/introspection.rs +++ b/crates/dagger-core/src/introspection.rs @@ -161,6 +161,9 @@ pub struct FullTypeFields { pub type_: Option, pub is_deprecated: Option, pub deprecation_reason: Option, + + #[serde(skip)] + pub parent_type: Option, } #[derive(Clone, Debug, Deserialize)]