feature/add impl (#6)

* format code

* with object gen and args

* add implementation

* add rust generator

* reset generated code

* add basic output

* reset output

* add object

* add format function

* with opts

* fix vec

* add context to unwrap

* fix arguments

* with function body

* first complete generation: Still missing Vec<Obj>

* run full alpine

* add roadmap item
This commit is contained in:
2023-02-17 12:33:16 +01:00
committed by GitHub
parent 2eb027754b
commit 4a4c03f3c2
30 changed files with 2478 additions and 1724 deletions

View File

@@ -0,0 +1,33 @@
use dagger_core::introspection::FullType;
use genco::prelude::rust;
use genco::quote;
fn render_enum_values(values: &FullType) -> Option<rust::Tokens> {
let values = values
.enum_values
.as_ref()
.into_iter()
.map(|values| {
values
.into_iter()
.map(|val| quote! { $(val.name.as_ref()) })
})
.flatten()
.collect::<Vec<_>>();
let mut tokens = rust::Tokens::new();
for val in values {
tokens.append(val);
tokens.push();
}
Some(tokens)
}
pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> {
Ok(quote! {
pub enum $(t.name.as_ref()) {
$(render_enum_values(t))
}
})
}

View File

@@ -0,0 +1,38 @@
use dagger_core::introspection::{FullType, FullTypeInputFields};
use genco::prelude::rust;
use genco::quote;
use crate::functions::CommonFunctions;
use crate::rust::functions::{format_name, format_struct_name};
pub fn render_input(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> {
let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
#[derive($serialize, $deserialize)]
pub struct $(format_name(t.name.as_ref().unwrap())) {
$(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) ))
}
})
}
pub fn render_input_fields(
funcs: &CommonFunctions,
fields: &[FullTypeInputFields],
) -> Option<rust::Tokens> {
let rendered_fields = fields.iter().map(|f| render_input_field(funcs, f));
if rendered_fields.len() == 0 {
None
} else {
Some(quote! {
$(for field in rendered_fields join ($['\r']) => $field)
})
}
}
pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens {
quote! {
pub $(format_struct_name(&field.input_value.name)): $(funcs.format_input_type(&field.input_value.type_)),
}
}

View File

@@ -0,0 +1,4 @@
pub mod enum_tmpl;
pub mod input_tmpl;
pub mod object_tmpl;
pub mod scalar_tmpl;

View File

@@ -0,0 +1,112 @@
use dagger_core::introspection::{FullType, FullTypeFields, FullTypeFieldsArgs};
use genco::prelude::rust;
use genco::quote;
use crate::functions::{type_ref_is_optional, CommonFunctions};
use crate::rust::functions::{
field_options_struct_name, format_function, format_name, format_struct_name,
};
use crate::utility::OptionExt;
pub fn render_object(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> {
let selection = rust::import("crate::querybuilder", "Selection");
let child = rust::import("std::process", "Child");
let conn = rust::import("dagger_core::connect_params", "ConnectParams");
let arc = rust::import("std::sync", "Arc");
Ok(quote! {
pub struct $(t.name.pipe(|s| format_name(s))) {
pub proc: $arc<$child>,
pub selection: $selection,
pub conn: $conn,
}
$(t.fields.pipe(|f| render_optional_args(funcs, f)))
impl $(t.name.pipe(|s| format_name(s))) {
$(t.fields.pipe(|f| render_functions(funcs, f)))
}
})
}
fn render_optional_args(
funcs: &CommonFunctions,
fields: &Vec<FullTypeFields>,
) -> Option<rust::Tokens> {
let rendered_fields = fields
.iter()
.map(|f| render_optional_arg(funcs, f))
.flatten()
.collect::<Vec<_>>();
if rendered_fields.len() == 0 {
None
} else {
Some(quote! {
$(for field in rendered_fields join ($['\r']) => $field)
})
}
}
fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
let output_type = field_options_struct_name(field);
let fields = field
.args
.pipe(|t| t.into_iter().flatten().collect::<Vec<_>>())
.map(|t| {
t.into_iter()
.filter(|t| type_ref_is_optional(&t.input_value.type_))
.collect::<Vec<_>>()
})
.pipe(|t| render_optional_field_args(funcs, t))
.flatten();
if let Some(fields) = fields {
Some(quote! {
pub struct $output_type {
$fields
}
})
} else {
None
}
}
fn render_optional_field_args(
funcs: &CommonFunctions,
args: &Vec<&FullTypeFieldsArgs>,
) -> Option<rust::Tokens> {
if args.len() == 0 {
return None;
}
let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| {
quote! {
pub $(format_struct_name(&a.name)): Option<$(funcs.format_output_type(&a.type_))>,
}
});
Some(quote! {
$(for arg in rendered_args join ($['\r']) => $arg)
})
}
fn render_functions(funcs: &CommonFunctions, fields: &Vec<FullTypeFields>) -> Option<rust::Tokens> {
let rendered_functions = fields
.iter()
.map(|f| render_function(funcs, f))
.collect::<Vec<_>>();
if rendered_functions.len() > 0 {
Some(quote! {
$(for func in rendered_functions join ($['\r']) => $func)
})
} else {
None
}
}
fn render_function(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
Some(quote! {
$(format_function(funcs, field))
})
}

View File

@@ -0,0 +1,16 @@
use dagger_core::introspection::FullType;
use genco::prelude::rust;
use genco::quote;
use crate::rust::functions::format_name;
use crate::utility::OptionExt;
pub fn render_scalar(t: &FullType) -> eyre::Result<rust::Tokens> {
let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
#[derive($serialize, $deserialize)]
pub struct $(t.name.pipe(|n|format_name(n)))(String);
})
}