From 8fd6bb983ef00b1aa2cf1ba3088028329033c38f Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 14 Mar 2023 14:56:49 +0100 Subject: [PATCH] fix: serialization of enum args for graphql (#34) --- crates/dagger-codegen/src/functions.rs | 16 +++++++++++ crates/dagger-codegen/src/rust/functions.rs | 18 ++++++++++-- crates/dagger-sdk/Cargo.toml | 2 +- crates/dagger-sdk/src/gen.rs | 8 +++--- crates/dagger-sdk/src/querybuilder.rs | 31 ++++++++++++++++++++- crates/dagger-sdk/tests/issues/iss_33.rs | 29 +++++++++++++++++++ crates/dagger-sdk/tests/issues/mod.rs | 1 + 7 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 crates/dagger-sdk/tests/issues/iss_33.rs diff --git a/crates/dagger-codegen/src/functions.rs b/crates/dagger-codegen/src/functions.rs index 0cbc7ba..56e879e 100644 --- a/crates/dagger-codegen/src/functions.rs +++ b/crates/dagger-codegen/src/functions.rs @@ -196,6 +196,22 @@ pub fn type_ref_is_scalar(type_ref: &TypeRef) -> bool { .unwrap_or(false) } +pub fn type_ref_is_enum(type_ref: &TypeRef) -> bool { + let mut type_ref = type_ref.clone(); + if type_ref + .kind + .pipe(|k| *k == __TypeKind::NON_NULL) + .unwrap_or(false) + { + type_ref = *type_ref.of_type.unwrap().clone(); + } + + type_ref + .kind + .pipe(|k| *k == __TypeKind::ENUM) + .unwrap_or(false) +} + pub fn type_ref_is_object(type_ref: &TypeRef) -> bool { let mut type_ref = type_ref.clone(); if type_ref diff --git a/crates/dagger-codegen/src/rust/functions.rs b/crates/dagger-codegen/src/rust/functions.rs index 7cee7c7..f097f50 100644 --- a/crates/dagger-codegen/src/rust/functions.rs +++ b/crates/dagger-codegen/src/rust/functions.rs @@ -5,8 +5,8 @@ use genco::quote; use genco::tokens::quoted; use crate::functions::{ - type_field_has_optional, type_ref_is_list, type_ref_is_list_of_objects, type_ref_is_object, - type_ref_is_optional, type_ref_is_scalar, CommonFunctions, Scalar, + type_field_has_optional, type_ref_is_enum, type_ref_is_list, type_ref_is_list_of_objects, + type_ref_is_object, type_ref_is_optional, type_ref_is_scalar, CommonFunctions, Scalar, }; use crate::utility::OptionExt; @@ -133,6 +133,12 @@ fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt } } + if type_ref_is_enum(&s.input_value.type_) { + return Some(quote! { + query = query.arg_enum($(quoted(name)), $(n)); + }) + } + if type_ref_is_list(&s.input_value.type_) { let inner = *s .input_value @@ -187,6 +193,14 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt let n = format_struct_name(&s.input_value.name); let name = &s.input_value.name; + if type_ref_is_enum(&s.input_value.type_) { + return Some(quote! { + if let Some($(&n)) = opts.$(&n) { + query = query.arg_enum($(quoted(name)), $(n)); + } + }); + } + Some(quote! { if let Some($(&n)) = opts.$(&n) { query = query.arg($(quoted(name)), $(&n)); diff --git a/crates/dagger-sdk/Cargo.toml b/crates/dagger-sdk/Cargo.toml index e234a2d..208117b 100644 --- a/crates/dagger-sdk/Cargo.toml +++ b/crates/dagger-sdk/Cargo.toml @@ -18,7 +18,7 @@ eyre = "0.6.8" futures = "0.3.27" gql_client = "1.0.7" serde = { version = "1.0.152", features = ["derive"] } -serde_json = "1.0.93" +serde_json = { version = "1.0.93", features = ["raw_value"] } tokio = { version = "1.25.0", features = ["full"] } derive_builder = "0.12.0" diff --git a/crates/dagger-sdk/src/gen.rs b/crates/dagger-sdk/src/gen.rs index d146e17..c794c0d 100644 --- a/crates/dagger-sdk/src/gen.rs +++ b/crates/dagger-sdk/src/gen.rs @@ -955,7 +955,7 @@ impl Container { query = query.arg("port", port); if let Some(protocol) = opts.protocol { - query = query.arg("protocol", protocol); + query = query.arg_enum("protocol", protocol); } if let Some(description) = opts.description { query = query.arg("description", description); @@ -1085,7 +1085,7 @@ impl Container { query = query.arg("source", source); } if let Some(sharing) = opts.sharing { - query = query.arg("sharing", sharing); + query = query.arg_enum("sharing", sharing); } return Container { @@ -1395,7 +1395,7 @@ impl Container { query = query.arg("port", port); if let Some(protocol) = opts.protocol { - query = query.arg("protocol", protocol); + query = query.arg_enum("protocol", protocol); } return Container { @@ -2848,9 +2848,9 @@ impl Socket { } #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub enum CacheSharingMode { + LOCKED, SHARED, PRIVATE, - LOCKED, } #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub enum NetworkProtocol { diff --git a/crates/dagger-sdk/src/querybuilder.rs b/crates/dagger-sdk/src/querybuilder.rs index 6714e1a..7fbe96b 100644 --- a/crates/dagger-sdk/src/querybuilder.rs +++ b/crates/dagger-sdk/src/querybuilder.rs @@ -68,6 +68,32 @@ impl Selection { s } + pub fn arg_enum(&self, name: &str, value: S) -> Selection + where + S: Serialize, + { + let mut s = self.clone(); + + let val = serde_json::to_string(&value).unwrap(); + let val = val[1..val.len() - 1].to_string(); + + println!("test"); + println!("{}", val); + + match s.args.as_mut() { + Some(args) => { + let _ = args.insert(name.to_string(), val); + } + None => { + let mut hm = HashMap::new(); + let _ = hm.insert(name.to_string(), val); + s.args = Some(hm); + } + } + + s + } + pub fn build(&self) -> eyre::Result { let mut fields = vec!["query".to_string()]; @@ -76,7 +102,7 @@ impl Selection { if let Some(args) = sel.args { let actualargs = args .iter() - .map(|(name, arg)| format!("{name}:{arg}")) + .map(|(name, arg)| format!("{name}:{}", arg.as_str())) .collect::>(); query = query.add(&format!("({})", actualargs.join(", "))); @@ -99,6 +125,9 @@ impl Selection { { let query = self.build()?; + let qbs = query.as_str(); + println!("{}", qbs); + let resp: Option = match gql_client.query(&query).await { Ok(r) => r, Err(e) => eyre::bail!(e), diff --git a/crates/dagger-sdk/tests/issues/iss_33.rs b/crates/dagger-sdk/tests/issues/iss_33.rs new file mode 100644 index 0000000..d397458 --- /dev/null +++ b/crates/dagger-sdk/tests/issues/iss_33.rs @@ -0,0 +1,29 @@ +use dagger_sdk::{ContainerWithExposedPortOpts, NetworkProtocol}; + +#[tokio::test] +async fn test_issue_30_alt() -> eyre::Result<()> { + let client = dagger_sdk::connect().await?; + + client + .container() + .from("denoland/deno:debian-1.30.3") + .with_exposed_port_opts( + 53, + ContainerWithExposedPortOpts { + protocol: Some(NetworkProtocol::TCP), + description: None, + }, + ) + .with_exposed_port_opts( + 53, + ContainerWithExposedPortOpts { + protocol: Some(NetworkProtocol::UDP), + description: None, + }, + ) + .with_exec(vec!["echo", "hello"]) + .exit_code() + .await?; + + Ok(()) +} diff --git a/crates/dagger-sdk/tests/issues/mod.rs b/crates/dagger-sdk/tests/issues/mod.rs index fa13322..d1b4afa 100644 --- a/crates/dagger-sdk/tests/issues/mod.rs +++ b/crates/dagger-sdk/tests/issues/mod.rs @@ -1 +1,2 @@ mod iss_30; +mod iss_33;