feat(sdk): move to &str instead of String and introduce builder.

This will make the api much easier to use, as we can now rely on ""
instead of "".into() for normal string values.

Introduced builder as well, which makes it much easier to use *Opts, as
it can handle the building of that, and get the benefits from String ->
&str, as that is currently not allowed for optional values
This commit is contained in:
Kasper Juul Hermansen 2023-02-19 17:21:40 +01:00
parent 6e2292cf11
commit c14cd64453
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
18 changed files with 505 additions and 304 deletions

73
Cargo.lock generated
View File

@ -352,6 +352,7 @@ version = "0.2.4"
dependencies = [ dependencies = [
"base64", "base64",
"dagger-core 0.2.2", "dagger-core 0.2.2",
"derive_builder",
"eyre", "eyre",
"futures", "futures",
"genco", "genco",
@ -363,6 +364,72 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "darling"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "derive_builder"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_builder_macro"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
dependencies = [
"derive_builder_core",
"syn",
]
[[package]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.13"
@ -839,6 +906,12 @@ dependencies = [
"tokio-native-tls", "tokio-native-tls",
] ]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.3.0" version = "0.3.0"

View File

@ -6,8 +6,8 @@ use eyre::ContextCompat;
use crate::utility::OptionExt; use crate::utility::OptionExt;
pub trait FormatTypeFuncs { pub trait FormatTypeFuncs {
fn format_kind_list(&self, representation: &str) -> String; fn format_kind_list(&self, representation: &str, input: bool, immutable: bool) -> String;
fn format_kind_scalar_string(&self, representation: &str) -> String; fn format_kind_scalar_string(&self, representation: &str, input: bool) -> String;
fn format_kind_scalar_int(&self, representation: &str) -> String; fn format_kind_scalar_int(&self, representation: &str) -> String;
fn format_kind_scalar_float(&self, representation: &str) -> String; fn format_kind_scalar_float(&self, representation: &str) -> String;
fn format_kind_scalar_boolean(&self, representation: &str) -> String; fn format_kind_scalar_boolean(&self, representation: &str) -> String;
@ -36,14 +36,18 @@ impl CommonFunctions {
} }
pub fn format_input_type(&self, t: &TypeRef) -> String { pub fn format_input_type(&self, t: &TypeRef) -> String {
self.format_type(t, true) self.format_type(t, true, false)
} }
pub fn format_output_type(&self, t: &TypeRef) -> String { pub fn format_output_type(&self, t: &TypeRef) -> String {
self.format_type(t, false) self.format_type(t, false, false)
} }
fn format_type(&self, t: &TypeRef, input: bool) -> String { pub fn format_immutable_input_type(&self, t: &TypeRef) -> String {
self.format_type(t, true, true)
}
fn format_type(&self, t: &TypeRef, input: bool, immutable: bool) -> String {
let mut representation = String::new(); let mut representation = String::new();
let mut r = Some(t.clone()); let mut r = Some(t.clone());
while r.is_some() { while r.is_some() {
@ -57,9 +61,14 @@ impl CommonFunctions {
Scalar::Float => self Scalar::Float => self
.format_type_funcs .format_type_funcs
.format_kind_scalar_float(&mut representation), .format_kind_scalar_float(&mut representation),
Scalar::String => self Scalar::String => {
.format_type_funcs if immutable {
.format_kind_scalar_string(&mut representation), "&'a str".into()
} else {
self.format_type_funcs
.format_kind_scalar_string(&mut representation, input)
}
}
Scalar::Boolean => self Scalar::Boolean => self
.format_type_funcs .format_type_funcs
.format_kind_scalar_boolean(&mut representation), .format_kind_scalar_boolean(&mut representation),
@ -87,12 +96,15 @@ impl CommonFunctions {
.as_ref() .as_ref()
.map(|t| t.clone()) .map(|t| t.clone())
.map(|t| *t) .map(|t| *t)
.map(|t| self.format_type(&t, input)) .map(|t| self.format_type(&t, input, immutable))
.context("could not get inner type of list") .context("could not get inner type of list")
.unwrap(); .unwrap();
representation = representation = self.format_type_funcs.format_kind_list(
self.format_type_funcs.format_kind_list(&mut inner_type); &mut inner_type,
input,
immutable,
);
return representation; return representation;
} }

View File

@ -5,13 +5,17 @@ use super::functions::format_name;
pub struct FormatTypeFunc; pub struct FormatTypeFunc;
impl FormatTypeFuncs for FormatTypeFunc { impl FormatTypeFuncs for FormatTypeFunc {
fn format_kind_list(&self, representation: &str) -> String { fn format_kind_list(&self, representation: &str, _input: bool, _immutable: bool) -> String {
format!("Vec<{}>", representation) format!("Vec<{}>", representation)
} }
fn format_kind_scalar_string(&self, representation: &str) -> String { fn format_kind_scalar_string(&self, representation: &str, input: bool) -> String {
let mut rep = representation.to_string(); let mut rep = representation.to_string();
if input {
rep.push_str("impl Into<String>");
} else {
rep.push_str("String"); rep.push_str("String");
}
rep rep
} }

View File

@ -5,8 +5,8 @@ use genco::quote;
use genco::tokens::quoted; use genco::tokens::quoted;
use crate::functions::{ use crate::functions::{
type_field_has_optional, type_ref_is_list_of_objects, type_ref_is_object, type_ref_is_optional, type_field_has_optional, type_ref_is_list, type_ref_is_list_of_objects, type_ref_is_object,
CommonFunctions, type_ref_is_optional, type_ref_is_scalar, CommonFunctions, Scalar,
}; };
use crate::utility::OptionExt; use crate::utility::OptionExt;
@ -66,6 +66,40 @@ fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
let n = format_struct_name(&s.input_value.name); let n = format_struct_name(&s.input_value.name);
let name = &s.input_value.name; let name = &s.input_value.name;
if type_ref_is_scalar(&s.input_value.type_) {
if let Scalar::String =
Scalar::from(&*s.input_value.type_.of_type.as_ref().unwrap().clone())
{
return Some(quote! {
query = query.arg($(quoted(name)), $(&n).into());
});
}
}
if type_ref_is_list(&s.input_value.type_) {
let inner = *s
.input_value
.type_
.of_type
.as_ref()
.unwrap()
.clone()
.of_type
.as_ref()
.unwrap()
.clone();
println!("type: {:?}", inner);
if type_ref_is_scalar(&inner) {
if let Scalar::String =
Scalar::from(&*inner.of_type.as_ref().unwrap().clone())
{
return Some(quote! {
query = query.arg($(quoted(name)), $(&n).into_iter().map(|i| i.into()).collect::<Vec<String>>());
});
}
}
}
Some(quote! { Some(quote! {
query = query.arg($(quoted(name)), $(n)); query = query.arg($(quoted(name)), $(n));
}) })

View File

@ -28,7 +28,7 @@ pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> {
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
Ok(quote! { Ok(quote! {
#[derive($serialize)] #[derive($serialize, Clone, PartialEq, Debug)]
pub enum $(t.name.as_ref()) { pub enum $(t.name.as_ref()) {
$(render_enum_values(t)) $(render_enum_values(t))
} }

View File

@ -9,7 +9,7 @@ pub fn render_input(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust:
let deserialize = rust::import("serde", "Deserialize"); let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
Ok(quote! { Ok(quote! {
#[derive($serialize, $deserialize)] #[derive($serialize, $deserialize, Debug, PartialEq, Clone)]
pub struct $(format_name(t.name.as_ref().unwrap())) { pub struct $(format_name(t.name.as_ref().unwrap())) {
$(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) )) $(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) ))
} }
@ -33,6 +33,6 @@ pub fn render_input_fields(
pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens { pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens {
quote! { quote! {
pub $(format_struct_name(&field.input_value.name)): $(funcs.format_input_type(&field.input_value.type_)), pub $(format_struct_name(&field.input_value.name)): $(funcs.format_output_type(&field.input_value.type_)),
} }
} }

View File

@ -61,9 +61,15 @@ fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Optio
.pipe(|t| render_optional_field_args(funcs, t)) .pipe(|t| render_optional_field_args(funcs, t))
.flatten(); .flatten();
let builder = rust::import("derive_builder", "Builder");
let phantom_data = rust::import("std::marker", "PhantomData");
if let Some(fields) = fields { if let Some(fields) = fields {
Some(quote! { Some(quote! {
pub struct $output_type { #[derive($builder, Debug, PartialEq)]
pub struct $output_type<'a> {
//#[builder(default, setter(skip))]
//pub marker: $(phantom_data)<&'a ()>,
$fields $fields
} }
}) })
@ -81,7 +87,8 @@ fn render_optional_field_args(
} }
let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| { let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| {
quote! { quote! {
pub $(format_struct_name(&a.name)): Option<$(funcs.format_output_type(&a.type_))>, #[builder(setter(into, strip_option))]
pub $(format_struct_name(&a.name)): Option<$(funcs.format_immutable_input_type(&a.type_))>,
} }
}); });

View File

@ -10,7 +10,7 @@ pub fn render_scalar(t: &FullType) -> eyre::Result<rust::Tokens> {
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
Ok(quote! { Ok(quote! {
#[derive($serialize, $deserialize)] #[derive($serialize, $deserialize, PartialEq, Debug, Clone)]
pub struct $(t.name.pipe(|n|format_name(n)))(String); pub struct $(t.name.pipe(|n|format_name(n)))(String);
}) })
} }

View File

@ -20,6 +20,7 @@ gql_client = "1.0.7"
serde = { version = "1.0.152", features = ["derive"] } serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93" serde_json = "1.0.93"
tokio = { version = "1.25.0", features = ["full"] } tokio = { version = "1.25.0", features = ["full"] }
derive_builder = "0.12.0"
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"

View File

@ -4,37 +4,30 @@ fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect()?; let client = dagger_sdk::connect()?;
let host_source_dir = client.host().directory( let host_source_dir = client.host().directory(
"examples/build-the-application/app".into(), "examples/build-the-application/app",
Some(HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]), exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None, include: None,
marker: std::marker::PhantomData,
}), }),
); );
let source = client let source = client
.container(None) .container(None)
.from("node:16".into()) .from("node:16")
.with_mounted_directory("/src".into(), host_source_dir.id()?); .with_mounted_directory("/src", host_source_dir.id()?);
let runner = source let runner = source
.with_workdir("/src".into()) .with_workdir("/src")
.with_exec(vec!["npm".into(), "install".into()], None); .with_exec(vec!["npm", "install"], None);
let test = runner.with_exec( let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"], None);
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None) .with_exec(vec!["npm", "run", "build"], None)
.directory("./build".into()); .directory("./build");
let _ = build_dir.export("./build".into()); let _ = build_dir.export("./build");
let entries = build_dir.entries(None); let entries = build_dir.entries(None);

View File

@ -1,49 +1,41 @@
use dagger_sdk::HostDirectoryOpts;
use rand::Rng; use rand::Rng;
fn main() -> eyre::Result<()> { fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect()?; let client = dagger_sdk::connect()?;
let host_source_dir = client.host().directory( let host_source_dir = client.host().directory(
"./examples/caching/app".into(), "./examples/caching/app",
Some(HostDirectoryOpts { Some(
exclude: Some(vec!["node_modules".into(), "ci/".into()]), dagger_sdk::HostDirectoryOptsBuilder::default()
include: None, .exclude(vec!["node_modules", "ci/"])
}), .build()?,
),
); );
let node_cache = client.cache_volume("node".into()).id()?; let node_cache = client.cache_volume("node").id()?;
let source = client let source = client
.container(None) .container(None)
.from("node:16".into()) .from("node:16")
.with_mounted_directory("/src".into(), host_source_dir.id()?) .with_mounted_directory("/src", host_source_dir.id()?)
.with_mounted_cache("/src/node_modules".into(), node_cache, None); .with_mounted_cache("/src/node_modules", node_cache, None);
let runner = source let runner = source
.with_workdir("/src".into()) .with_workdir("/src")
.with_exec(vec!["npm".into(), "install".into()], None); .with_exec(vec!["npm", "install"], None);
let test = runner.with_exec( let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"], None);
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None) .with_exec(vec!["npm", "run", "build"], None)
.directory("./build".into()); .directory("./build");
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container(None) .container(None)
.from("nginx".into()) .from("nginx")
.with_directory("/usr/share/nginx/html".into(), build_dir.id()?, None) .with_directory("/usr/share/nginx/html", build_dir.id()?, None)
.publish( .publish(
format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()), format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None, None,

View File

@ -7,7 +7,7 @@ fn main() -> eyre::Result<()> {
let context_dir = client let context_dir = client
.host() .host()
.directory("./examples/existing-dockerfile/app".into(), None); .directory("./examples/existing-dockerfile/app", None);
let ref_ = client let ref_ = client
.container(None) .container(None)

View File

@ -3,8 +3,8 @@ fn main() -> eyre::Result<()> {
let version = client let version = client
.container(None) .container(None)
.from("golang:1.19".into()) .from("golang:1.19")
.with_exec(vec!["go".into(), "version".into()], None) .with_exec(vec!["go", "version".into()], None)
.stdout()?; .stdout()?;
println!("Hello from Dagger and {}", version.trim()); println!("Hello from Dagger and {}", version.trim());

View File

@ -5,42 +5,35 @@ fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect()?; let client = dagger_sdk::connect()?;
let host_source_dir = client.host().directory( let host_source_dir = client.host().directory(
"examples/publish-the-application/app".into(), "examples/publish-the-application/app",
Some(HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]), exclude: Some(vec!["node_modules", "ci/"]),
include: None, include: None,
marker: std::marker::PhantomData,
}), }),
); );
let source = client let source = client
.container(None) .container(None)
.from("node:16".into()) .from("node:16")
.with_mounted_directory("/src".into(), host_source_dir.id()?); .with_mounted_directory("/src", host_source_dir.id()?);
let runner = source let runner = source
.with_workdir("/src".into()) .with_workdir("/src")
.with_exec(vec!["npm".into(), "install".into()], None); .with_exec(vec!["npm", "install"], None);
let test = runner.with_exec( let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"], None);
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None) .with_exec(vec!["npm", "run", "build"], None)
.directory("./build".into()); .directory("./build");
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container(None) .container(None)
.from("nginx".into()) .from("nginx")
.with_directory("/usr/share/nginx/html".into(), build_dir.id()?, None) .with_directory("/usr/share/nginx/html", build_dir.id()?, None)
.publish( .publish(
format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()), format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None, None,

View File

@ -6,45 +6,38 @@ fn main() -> eyre::Result<()> {
let output = "examples/publish-the-application/app/build"; let output = "examples/publish-the-application/app/build";
let host_source_dir = client.host().directory( let host_source_dir = client.host().directory(
"examples/publish-the-application/app".into(), "examples/publish-the-application/app",
Some(HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]), exclude: Some(vec!["node_modules", "ci/"]),
include: None, include: None,
marker: std::marker::PhantomData,
}), }),
); );
let source = client let source = client
.container(None) .container(None)
.from("node:16".into()) .from("node:16")
.with_mounted_directory("/src".into(), host_source_dir.id()?); .with_mounted_directory("/src", host_source_dir.id()?);
let runner = source let runner = source
.with_workdir("/src".into()) .with_workdir("/src")
.with_exec(vec!["npm".into(), "install".into()], None); .with_exec(vec!["npm", "install"], None);
let test = runner.with_exec( let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"], None);
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let _ = test let _ = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None) .with_exec(vec!["npm", "run", "build"], None)
.directory("./build".into()) .directory("./build")
.export(output.into()); .export(output);
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container(None) .container(None)
.from("nginx".into()) .from("nginx")
.with_directory( .with_directory(
"/usr/share/nginx/html".into(), "/usr/share/nginx/html",
client.host().directory(output.into(), None).id()?, client.host().directory(output, None).id()?,
None, None,
) )
.publish( .publish(

View File

@ -4,32 +4,25 @@ fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect()?; let client = dagger_sdk::connect()?;
let host_source_dir = client.host().directory( let host_source_dir = client.host().directory(
"examples/test-the-application/app".into(), "examples/test-the-application/app",
Some(HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]), exclude: Some(vec!["node_modules", "ci/"]),
include: None, include: None,
marker: std::marker::PhantomData,
}), }),
); );
let source = client let source = client
.container(None) .container(None)
.from("node:16".into()) .from("node:16")
.with_mounted_directory("/src".into(), host_source_dir.id()?); .with_mounted_directory("/src", host_source_dir.id()?);
let runner = source let runner = source
.with_workdir("/src".into()) .with_workdir("/src")
.with_exec(vec!["npm".into(), "install".into()], None); .with_exec(vec!["npm", "install"], None);
let out = runner let out = runner
.with_exec( .with_exec(vec!["npm", "test", "--", "--watchAll=false"], None)
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
)
.stderr()?; .stderr()?;
println!("{}", out); println!("{}", out);

View File

@ -1,25 +1,26 @@
use crate::client::graphql_client; use crate::client::graphql_client;
use crate::querybuilder::Selection; use crate::querybuilder::Selection;
use dagger_core::connect_params::ConnectParams; use dagger_core::connect_params::ConnectParams;
use derive_builder::Builder;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::process::Child; use std::process::Child;
use std::sync::Arc; use std::sync::Arc;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct CacheId(String); pub struct CacheId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct ContainerId(String); pub struct ContainerId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct DirectoryId(String); pub struct DirectoryId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct FileId(String); pub struct FileId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct Platform(String); pub struct Platform(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct SecretId(String); pub struct SecretId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub struct SocketId(String); pub struct SocketId(String);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct BuildArg { pub struct BuildArg {
pub name: String, pub name: String,
pub value: String, pub value: String,
@ -43,49 +44,83 @@ pub struct Container {
pub conn: ConnectParams, pub conn: ConnectParams,
} }
pub struct ContainerBuildOpts { #[derive(Builder, Debug, PartialEq)]
pub dockerfile: Option<String>, pub struct ContainerBuildOpts<'a> {
#[builder(setter(into, strip_option))]
pub dockerfile: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub build_args: Option<Vec<BuildArg>>, pub build_args: Option<Vec<BuildArg>>,
pub target: Option<String>, #[builder(setter(into, strip_option))]
pub target: Option<&'a str>,
} }
pub struct ContainerExecOpts { #[derive(Builder, Debug, PartialEq)]
pub args: Option<Vec<String>>, pub struct ContainerExecOpts<'a> {
pub stdin: Option<String>, #[builder(setter(into, strip_option))]
pub redirect_stdout: Option<String>, pub args: Option<Vec<&'a str>>,
pub redirect_stderr: Option<String>, #[builder(setter(into, strip_option))]
pub stdin: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub redirect_stdout: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub redirect_stderr: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub experimental_privileged_nesting: Option<bool>, pub experimental_privileged_nesting: Option<bool>,
} }
pub struct ContainerExportOpts { #[derive(Builder, Debug, PartialEq)]
pub struct ContainerExportOpts<'a> {
#[builder(setter(into, strip_option))]
pub platform_variants: Option<Vec<ContainerId>>, pub platform_variants: Option<Vec<ContainerId>>,
} }
pub struct ContainerPipelineOpts { #[derive(Builder, Debug, PartialEq)]
pub description: Option<String>, pub struct ContainerPipelineOpts<'a> {
#[builder(setter(into, strip_option))]
pub description: Option<&'a str>,
} }
pub struct ContainerPublishOpts { #[derive(Builder, Debug, PartialEq)]
pub struct ContainerPublishOpts<'a> {
#[builder(setter(into, strip_option))]
pub platform_variants: Option<Vec<ContainerId>>, pub platform_variants: Option<Vec<ContainerId>>,
} }
pub struct ContainerWithDefaultArgsOpts { #[derive(Builder, Debug, PartialEq)]
pub args: Option<Vec<String>>, pub struct ContainerWithDefaultArgsOpts<'a> {
#[builder(setter(into, strip_option))]
pub args: Option<Vec<&'a str>>,
} }
pub struct ContainerWithDirectoryOpts { #[derive(Builder, Debug, PartialEq)]
pub exclude: Option<Vec<String>>, pub struct ContainerWithDirectoryOpts<'a> {
pub include: Option<Vec<String>>, #[builder(setter(into, strip_option))]
pub exclude: Option<Vec<&'a str>>,
#[builder(setter(into, strip_option))]
pub include: Option<Vec<&'a str>>,
} }
pub struct ContainerWithExecOpts { #[derive(Builder, Debug, PartialEq)]
pub stdin: Option<String>, pub struct ContainerWithExecOpts<'a> {
pub redirect_stdout: Option<String>, #[builder(setter(into, strip_option))]
pub redirect_stderr: Option<String>, pub stdin: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub redirect_stdout: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub redirect_stderr: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub experimental_privileged_nesting: Option<bool>, pub experimental_privileged_nesting: Option<bool>,
} }
pub struct ContainerWithFileOpts { #[derive(Builder, Debug, PartialEq)]
pub struct ContainerWithFileOpts<'a> {
#[builder(setter(into, strip_option))]
pub permissions: Option<isize>, pub permissions: Option<isize>,
} }
pub struct ContainerWithMountedCacheOpts { #[derive(Builder, Debug, PartialEq)]
pub struct ContainerWithMountedCacheOpts<'a> {
#[builder(setter(into, strip_option))]
pub source: Option<DirectoryId>, pub source: Option<DirectoryId>,
#[builder(setter(into, strip_option))]
pub sharing: Option<CacheSharingMode>, pub sharing: Option<CacheSharingMode>,
} }
pub struct ContainerWithNewFileOpts { #[derive(Builder, Debug, PartialEq)]
pub contents: Option<String>, pub struct ContainerWithNewFileOpts<'a> {
#[builder(setter(into, strip_option))]
pub contents: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub permissions: Option<isize>, pub permissions: Option<isize>,
} }
@ -117,10 +152,10 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn directory(&self, path: String) -> Directory { pub fn directory(&self, path: impl Into<String>) -> Directory {
let mut query = self.selection.select("directory"); let mut query = self.selection.select("directory");
query = query.arg("path", path); query = query.arg("path", path.into());
return Directory { return Directory {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -133,10 +168,10 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn env_variable(&self, name: String) -> eyre::Result<String> { pub fn env_variable(&self, name: impl Into<String>) -> eyre::Result<String> {
let mut query = self.selection.select("envVariable"); let mut query = self.selection.select("envVariable");
query = query.arg("name", name); query = query.arg("name", name.into());
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
@ -184,10 +219,14 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn export(&self, path: String, opts: Option<ContainerExportOpts>) -> eyre::Result<bool> { pub fn export(
&self,
path: impl Into<String>,
opts: Option<ContainerExportOpts>,
) -> eyre::Result<bool> {
let mut query = self.selection.select("export"); let mut query = self.selection.select("export");
query = query.arg("path", path); query = query.arg("path", path.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(platform_variants) = opts.platform_variants { if let Some(platform_variants) = opts.platform_variants {
query = query.arg("platformVariants", platform_variants); query = query.arg("platformVariants", platform_variants);
@ -196,10 +235,10 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn file(&self, path: String) -> File { pub fn file(&self, path: impl Into<String>) -> File {
let mut query = self.selection.select("file"); let mut query = self.selection.select("file");
query = query.arg("path", path); query = query.arg("path", path.into());
return File { return File {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -207,10 +246,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn from(&self, address: String) -> Container { pub fn from(&self, address: impl Into<String>) -> Container {
let mut query = self.selection.select("from"); let mut query = self.selection.select("from");
query = query.arg("address", address); query = query.arg("address", address.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -232,10 +271,10 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn label(&self, name: String) -> eyre::Result<String> { pub fn label(&self, name: impl Into<String>) -> eyre::Result<String> {
let mut query = self.selection.select("label"); let mut query = self.selection.select("label");
query = query.arg("name", name); query = query.arg("name", name.into());
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
@ -253,10 +292,14 @@ impl Container {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn pipeline(&self, name: String, opts: Option<ContainerPipelineOpts>) -> Container { pub fn pipeline(
&self,
name: impl Into<String>,
opts: Option<ContainerPipelineOpts>,
) -> Container {
let mut query = self.selection.select("pipeline"); let mut query = self.selection.select("pipeline");
query = query.arg("name", name); query = query.arg("name", name.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(description) = opts.description { if let Some(description) = opts.description {
query = query.arg("description", description); query = query.arg("description", description);
@ -276,12 +319,12 @@ impl Container {
} }
pub fn publish( pub fn publish(
&self, &self,
address: String, address: impl Into<String>,
opts: Option<ContainerPublishOpts>, opts: Option<ContainerPublishOpts>,
) -> eyre::Result<String> { ) -> eyre::Result<String> {
let mut query = self.selection.select("publish"); let mut query = self.selection.select("publish");
query = query.arg("address", address); query = query.arg("address", address.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(platform_variants) = opts.platform_variants { if let Some(platform_variants) = opts.platform_variants {
query = query.arg("platformVariants", platform_variants); query = query.arg("platformVariants", platform_variants);
@ -331,13 +374,13 @@ impl Container {
} }
pub fn with_directory( pub fn with_directory(
&self, &self,
path: String, path: impl Into<String>,
directory: DirectoryId, directory: DirectoryId,
opts: Option<ContainerWithDirectoryOpts>, opts: Option<ContainerWithDirectoryOpts>,
) -> Container { ) -> Container {
let mut query = self.selection.select("withDirectory"); let mut query = self.selection.select("withDirectory");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("directory", directory); query = query.arg("directory", directory);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(exclude) = opts.exclude { if let Some(exclude) = opts.exclude {
@ -354,10 +397,13 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_entrypoint(&self, args: Vec<String>) -> Container { pub fn with_entrypoint(&self, args: Vec<impl Into<String>>) -> Container {
let mut query = self.selection.select("withEntrypoint"); let mut query = self.selection.select("withEntrypoint");
query = query.arg("args", args); query = query.arg(
"args",
args.into_iter().map(|i| i.into()).collect::<Vec<String>>(),
);
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -365,11 +411,15 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_env_variable(&self, name: String, value: String) -> Container { pub fn with_env_variable(
&self,
name: impl Into<String>,
value: impl Into<String>,
) -> Container {
let mut query = self.selection.select("withEnvVariable"); let mut query = self.selection.select("withEnvVariable");
query = query.arg("name", name); query = query.arg("name", name.into());
query = query.arg("value", value); query = query.arg("value", value.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -377,10 +427,17 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_exec(&self, args: Vec<String>, opts: Option<ContainerWithExecOpts>) -> Container { pub fn with_exec(
&self,
args: Vec<impl Into<String>>,
opts: Option<ContainerWithExecOpts>,
) -> Container {
let mut query = self.selection.select("withExec"); let mut query = self.selection.select("withExec");
query = query.arg("args", args); query = query.arg(
"args",
args.into_iter().map(|i| i.into()).collect::<Vec<String>>(),
);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(stdin) = opts.stdin { if let Some(stdin) = opts.stdin {
query = query.arg("stdin", stdin); query = query.arg("stdin", stdin);
@ -418,13 +475,13 @@ impl Container {
} }
pub fn with_file( pub fn with_file(
&self, &self,
path: String, path: impl Into<String>,
source: FileId, source: FileId,
opts: Option<ContainerWithFileOpts>, opts: Option<ContainerWithFileOpts>,
) -> Container { ) -> Container {
let mut query = self.selection.select("withFile"); let mut query = self.selection.select("withFile");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(permissions) = opts.permissions { if let Some(permissions) = opts.permissions {
@ -438,11 +495,11 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_label(&self, name: String, value: String) -> Container { pub fn with_label(&self, name: impl Into<String>, value: impl Into<String>) -> Container {
let mut query = self.selection.select("withLabel"); let mut query = self.selection.select("withLabel");
query = query.arg("name", name); query = query.arg("name", name.into());
query = query.arg("value", value); query = query.arg("value", value.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -452,13 +509,13 @@ impl Container {
} }
pub fn with_mounted_cache( pub fn with_mounted_cache(
&self, &self,
path: String, path: impl Into<String>,
cache: CacheId, cache: CacheId,
opts: Option<ContainerWithMountedCacheOpts>, opts: Option<ContainerWithMountedCacheOpts>,
) -> Container { ) -> Container {
let mut query = self.selection.select("withMountedCache"); let mut query = self.selection.select("withMountedCache");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("cache", cache); query = query.arg("cache", cache);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(source) = opts.source { if let Some(source) = opts.source {
@ -475,10 +532,14 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_mounted_directory(&self, path: String, source: DirectoryId) -> Container { pub fn with_mounted_directory(
&self,
path: impl Into<String>,
source: DirectoryId,
) -> Container {
let mut query = self.selection.select("withMountedDirectory"); let mut query = self.selection.select("withMountedDirectory");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
return Container { return Container {
@ -487,10 +548,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_mounted_file(&self, path: String, source: FileId) -> Container { pub fn with_mounted_file(&self, path: impl Into<String>, source: FileId) -> Container {
let mut query = self.selection.select("withMountedFile"); let mut query = self.selection.select("withMountedFile");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
return Container { return Container {
@ -499,10 +560,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_mounted_secret(&self, path: String, source: SecretId) -> Container { pub fn with_mounted_secret(&self, path: impl Into<String>, source: SecretId) -> Container {
let mut query = self.selection.select("withMountedSecret"); let mut query = self.selection.select("withMountedSecret");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
return Container { return Container {
@ -511,10 +572,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_mounted_temp(&self, path: String) -> Container { pub fn with_mounted_temp(&self, path: impl Into<String>) -> Container {
let mut query = self.selection.select("withMountedTemp"); let mut query = self.selection.select("withMountedTemp");
query = query.arg("path", path); query = query.arg("path", path.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -522,10 +583,14 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_new_file(&self, path: String, opts: Option<ContainerWithNewFileOpts>) -> Container { pub fn with_new_file(
&self,
path: impl Into<String>,
opts: Option<ContainerWithNewFileOpts>,
) -> Container {
let mut query = self.selection.select("withNewFile"); let mut query = self.selection.select("withNewFile");
query = query.arg("path", path); query = query.arg("path", path.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(contents) = opts.contents { if let Some(contents) = opts.contents {
query = query.arg("contents", contents); query = query.arg("contents", contents);
@ -543,14 +608,14 @@ impl Container {
} }
pub fn with_registry_auth( pub fn with_registry_auth(
&self, &self,
address: String, address: impl Into<String>,
username: String, username: impl Into<String>,
secret: SecretId, secret: SecretId,
) -> Container { ) -> Container {
let mut query = self.selection.select("withRegistryAuth"); let mut query = self.selection.select("withRegistryAuth");
query = query.arg("address", address); query = query.arg("address", address.into());
query = query.arg("username", username); query = query.arg("username", username.into());
query = query.arg("secret", secret); query = query.arg("secret", secret);
return Container { return Container {
@ -570,10 +635,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_secret_variable(&self, name: String, secret: SecretId) -> Container { pub fn with_secret_variable(&self, name: impl Into<String>, secret: SecretId) -> Container {
let mut query = self.selection.select("withSecretVariable"); let mut query = self.selection.select("withSecretVariable");
query = query.arg("name", name); query = query.arg("name", name.into());
query = query.arg("secret", secret); query = query.arg("secret", secret);
return Container { return Container {
@ -582,10 +647,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_unix_socket(&self, path: String, source: SocketId) -> Container { pub fn with_unix_socket(&self, path: impl Into<String>, source: SocketId) -> Container {
let mut query = self.selection.select("withUnixSocket"); let mut query = self.selection.select("withUnixSocket");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
return Container { return Container {
@ -594,10 +659,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_user(&self, name: String) -> Container { pub fn with_user(&self, name: impl Into<String>) -> Container {
let mut query = self.selection.select("withUser"); let mut query = self.selection.select("withUser");
query = query.arg("name", name); query = query.arg("name", name.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -605,10 +670,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn with_workdir(&self, path: String) -> Container { pub fn with_workdir(&self, path: impl Into<String>) -> Container {
let mut query = self.selection.select("withWorkdir"); let mut query = self.selection.select("withWorkdir");
query = query.arg("path", path); query = query.arg("path", path.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -616,10 +681,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_env_variable(&self, name: String) -> Container { pub fn without_env_variable(&self, name: impl Into<String>) -> Container {
let mut query = self.selection.select("withoutEnvVariable"); let mut query = self.selection.select("withoutEnvVariable");
query = query.arg("name", name); query = query.arg("name", name.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -627,10 +692,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_label(&self, name: String) -> Container { pub fn without_label(&self, name: impl Into<String>) -> Container {
let mut query = self.selection.select("withoutLabel"); let mut query = self.selection.select("withoutLabel");
query = query.arg("name", name); query = query.arg("name", name.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -638,10 +703,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_mount(&self, path: String) -> Container { pub fn without_mount(&self, path: impl Into<String>) -> Container {
let mut query = self.selection.select("withoutMount"); let mut query = self.selection.select("withoutMount");
query = query.arg("path", path); query = query.arg("path", path.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -649,10 +714,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_registry_auth(&self, address: String) -> Container { pub fn without_registry_auth(&self, address: impl Into<String>) -> Container {
let mut query = self.selection.select("withoutRegistryAuth"); let mut query = self.selection.select("withoutRegistryAuth");
query = query.arg("address", address); query = query.arg("address", address.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -660,10 +725,10 @@ impl Container {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_unix_socket(&self, path: String) -> Container { pub fn without_unix_socket(&self, path: impl Into<String>) -> Container {
let mut query = self.selection.select("withoutUnixSocket"); let mut query = self.selection.select("withoutUnixSocket");
query = query.arg("path", path); query = query.arg("path", path.into());
return Container { return Container {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -683,29 +748,47 @@ pub struct Directory {
pub conn: ConnectParams, pub conn: ConnectParams,
} }
pub struct DirectoryDockerBuildOpts { #[derive(Builder, Debug, PartialEq)]
pub dockerfile: Option<String>, pub struct DirectoryDockerBuildOpts<'a> {
#[builder(setter(into, strip_option))]
pub dockerfile: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub platform: Option<Platform>, pub platform: Option<Platform>,
#[builder(setter(into, strip_option))]
pub build_args: Option<Vec<BuildArg>>, pub build_args: Option<Vec<BuildArg>>,
pub target: Option<String>, #[builder(setter(into, strip_option))]
pub target: Option<&'a str>,
} }
pub struct DirectoryEntriesOpts { #[derive(Builder, Debug, PartialEq)]
pub path: Option<String>, pub struct DirectoryEntriesOpts<'a> {
#[builder(setter(into, strip_option))]
pub path: Option<&'a str>,
} }
pub struct DirectoryPipelineOpts { #[derive(Builder, Debug, PartialEq)]
pub description: Option<String>, pub struct DirectoryPipelineOpts<'a> {
#[builder(setter(into, strip_option))]
pub description: Option<&'a str>,
} }
pub struct DirectoryWithDirectoryOpts { #[derive(Builder, Debug, PartialEq)]
pub exclude: Option<Vec<String>>, pub struct DirectoryWithDirectoryOpts<'a> {
pub include: Option<Vec<String>>, #[builder(setter(into, strip_option))]
pub exclude: Option<Vec<&'a str>>,
#[builder(setter(into, strip_option))]
pub include: Option<Vec<&'a str>>,
} }
pub struct DirectoryWithFileOpts { #[derive(Builder, Debug, PartialEq)]
pub struct DirectoryWithFileOpts<'a> {
#[builder(setter(into, strip_option))]
pub permissions: Option<isize>, pub permissions: Option<isize>,
} }
pub struct DirectoryWithNewDirectoryOpts { #[derive(Builder, Debug, PartialEq)]
pub struct DirectoryWithNewDirectoryOpts<'a> {
#[builder(setter(into, strip_option))]
pub permissions: Option<isize>, pub permissions: Option<isize>,
} }
pub struct DirectoryWithNewFileOpts { #[derive(Builder, Debug, PartialEq)]
pub struct DirectoryWithNewFileOpts<'a> {
#[builder(setter(into, strip_option))]
pub permissions: Option<isize>, pub permissions: Option<isize>,
} }
@ -721,10 +804,10 @@ impl Directory {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn directory(&self, path: String) -> Directory { pub fn directory(&self, path: impl Into<String>) -> Directory {
let mut query = self.selection.select("directory"); let mut query = self.selection.select("directory");
query = query.arg("path", path); query = query.arg("path", path.into());
return Directory { return Directory {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -767,17 +850,17 @@ impl Directory {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn export(&self, path: String) -> eyre::Result<bool> { pub fn export(&self, path: impl Into<String>) -> eyre::Result<bool> {
let mut query = self.selection.select("export"); let mut query = self.selection.select("export");
query = query.arg("path", path); query = query.arg("path", path.into());
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn file(&self, path: String) -> File { pub fn file(&self, path: impl Into<String>) -> File {
let mut query = self.selection.select("file"); let mut query = self.selection.select("file");
query = query.arg("path", path); query = query.arg("path", path.into());
return File { return File {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -790,10 +873,10 @@ impl Directory {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn load_project(&self, config_path: String) -> Project { pub fn load_project(&self, config_path: impl Into<String>) -> Project {
let mut query = self.selection.select("loadProject"); let mut query = self.selection.select("loadProject");
query = query.arg("configPath", config_path); query = query.arg("configPath", config_path.into());
return Project { return Project {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -801,10 +884,14 @@ impl Directory {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn pipeline(&self, name: String, opts: Option<DirectoryPipelineOpts>) -> Directory { pub fn pipeline(
&self,
name: impl Into<String>,
opts: Option<DirectoryPipelineOpts>,
) -> Directory {
let mut query = self.selection.select("pipeline"); let mut query = self.selection.select("pipeline");
query = query.arg("name", name); query = query.arg("name", name.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(description) = opts.description { if let Some(description) = opts.description {
query = query.arg("description", description); query = query.arg("description", description);
@ -819,13 +906,13 @@ impl Directory {
} }
pub fn with_directory( pub fn with_directory(
&self, &self,
path: String, path: impl Into<String>,
directory: DirectoryId, directory: DirectoryId,
opts: Option<DirectoryWithDirectoryOpts>, opts: Option<DirectoryWithDirectoryOpts>,
) -> Directory { ) -> Directory {
let mut query = self.selection.select("withDirectory"); let mut query = self.selection.select("withDirectory");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("directory", directory); query = query.arg("directory", directory);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(exclude) = opts.exclude { if let Some(exclude) = opts.exclude {
@ -844,13 +931,13 @@ impl Directory {
} }
pub fn with_file( pub fn with_file(
&self, &self,
path: String, path: impl Into<String>,
source: FileId, source: FileId,
opts: Option<DirectoryWithFileOpts>, opts: Option<DirectoryWithFileOpts>,
) -> Directory { ) -> Directory {
let mut query = self.selection.select("withFile"); let mut query = self.selection.select("withFile");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("source", source); query = query.arg("source", source);
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(permissions) = opts.permissions { if let Some(permissions) = opts.permissions {
@ -866,12 +953,12 @@ impl Directory {
} }
pub fn with_new_directory( pub fn with_new_directory(
&self, &self,
path: String, path: impl Into<String>,
opts: Option<DirectoryWithNewDirectoryOpts>, opts: Option<DirectoryWithNewDirectoryOpts>,
) -> Directory { ) -> Directory {
let mut query = self.selection.select("withNewDirectory"); let mut query = self.selection.select("withNewDirectory");
query = query.arg("path", path); query = query.arg("path", path.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(permissions) = opts.permissions { if let Some(permissions) = opts.permissions {
query = query.arg("permissions", permissions); query = query.arg("permissions", permissions);
@ -886,14 +973,14 @@ impl Directory {
} }
pub fn with_new_file( pub fn with_new_file(
&self, &self,
path: String, path: impl Into<String>,
contents: String, contents: impl Into<String>,
opts: Option<DirectoryWithNewFileOpts>, opts: Option<DirectoryWithNewFileOpts>,
) -> Directory { ) -> Directory {
let mut query = self.selection.select("withNewFile"); let mut query = self.selection.select("withNewFile");
query = query.arg("path", path); query = query.arg("path", path.into());
query = query.arg("contents", contents); query = query.arg("contents", contents.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(permissions) = opts.permissions { if let Some(permissions) = opts.permissions {
query = query.arg("permissions", permissions); query = query.arg("permissions", permissions);
@ -917,10 +1004,10 @@ impl Directory {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_directory(&self, path: String) -> Directory { pub fn without_directory(&self, path: impl Into<String>) -> Directory {
let mut query = self.selection.select("withoutDirectory"); let mut query = self.selection.select("withoutDirectory");
query = query.arg("path", path); query = query.arg("path", path.into());
return Directory { return Directory {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -928,10 +1015,10 @@ impl Directory {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn without_file(&self, path: String) -> Directory { pub fn without_file(&self, path: impl Into<String>) -> Directory {
let mut query = self.selection.select("withoutFile"); let mut query = self.selection.select("withoutFile");
query = query.arg("path", path); query = query.arg("path", path.into());
return Directory { return Directory {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -970,10 +1057,10 @@ impl File {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn export(&self, path: String) -> eyre::Result<bool> { pub fn export(&self, path: impl Into<String>) -> eyre::Result<bool> {
let mut query = self.selection.select("export"); let mut query = self.selection.select("export");
query = query.arg("path", path); query = query.arg("path", path.into());
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
@ -1014,8 +1101,11 @@ pub struct GitRef {
pub conn: ConnectParams, pub conn: ConnectParams,
} }
pub struct GitRefTreeOpts { #[derive(Builder, Debug, PartialEq)]
pub ssh_known_hosts: Option<String>, pub struct GitRefTreeOpts<'a> {
#[builder(setter(into, strip_option))]
pub ssh_known_hosts: Option<&'a str>,
#[builder(setter(into, strip_option))]
pub ssh_auth_socket: Option<SocketId>, pub ssh_auth_socket: Option<SocketId>,
} }
@ -1051,10 +1141,10 @@ pub struct GitRepository {
} }
impl GitRepository { impl GitRepository {
pub fn branch(&self, name: String) -> GitRef { pub fn branch(&self, name: impl Into<String>) -> GitRef {
let mut query = self.selection.select("branch"); let mut query = self.selection.select("branch");
query = query.arg("name", name); query = query.arg("name", name.into());
return GitRef { return GitRef {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1067,10 +1157,10 @@ impl GitRepository {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
pub fn commit(&self, id: String) -> GitRef { pub fn commit(&self, id: impl Into<String>) -> GitRef {
let mut query = self.selection.select("commit"); let mut query = self.selection.select("commit");
query = query.arg("id", id); query = query.arg("id", id.into());
return GitRef { return GitRef {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1078,10 +1168,10 @@ impl GitRepository {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn tag(&self, name: String) -> GitRef { pub fn tag(&self, name: impl Into<String>) -> GitRef {
let mut query = self.selection.select("tag"); let mut query = self.selection.select("tag");
query = query.arg("name", name); query = query.arg("name", name.into());
return GitRef { return GitRef {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1101,20 +1191,26 @@ pub struct Host {
pub conn: ConnectParams, pub conn: ConnectParams,
} }
pub struct HostDirectoryOpts { #[derive(Builder, Debug, PartialEq)]
pub exclude: Option<Vec<String>>, pub struct HostDirectoryOpts<'a> {
pub include: Option<Vec<String>>, #[builder(setter(into, strip_option))]
pub exclude: Option<Vec<&'a str>>,
#[builder(setter(into, strip_option))]
pub include: Option<Vec<&'a str>>,
} }
pub struct HostWorkdirOpts { #[derive(Builder, Debug, PartialEq)]
pub exclude: Option<Vec<String>>, pub struct HostWorkdirOpts<'a> {
pub include: Option<Vec<String>>, #[builder(setter(into, strip_option))]
pub exclude: Option<Vec<&'a str>>,
#[builder(setter(into, strip_option))]
pub include: Option<Vec<&'a str>>,
} }
impl Host { impl Host {
pub fn directory(&self, path: String, opts: Option<HostDirectoryOpts>) -> Directory { pub fn directory(&self, path: impl Into<String>, opts: Option<HostDirectoryOpts>) -> Directory {
let mut query = self.selection.select("directory"); let mut query = self.selection.select("directory");
query = query.arg("path", path); query = query.arg("path", path.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(exclude) = opts.exclude { if let Some(exclude) = opts.exclude {
query = query.arg("exclude", exclude); query = query.arg("exclude", exclude);
@ -1130,10 +1226,10 @@ impl Host {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn env_variable(&self, name: String) -> HostVariable { pub fn env_variable(&self, name: impl Into<String>) -> HostVariable {
let mut query = self.selection.select("envVariable"); let mut query = self.selection.select("envVariable");
query = query.arg("name", name); query = query.arg("name", name.into());
return HostVariable { return HostVariable {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1141,10 +1237,10 @@ impl Host {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn unix_socket(&self, path: String) -> Socket { pub fn unix_socket(&self, path: impl Into<String>) -> Socket {
let mut query = self.selection.select("unixSocket"); let mut query = self.selection.select("unixSocket");
query = query.arg("path", path); query = query.arg("path", path.into());
return Socket { return Socket {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1263,28 +1359,39 @@ pub struct Query {
pub conn: ConnectParams, pub conn: ConnectParams,
} }
pub struct QueryContainerOpts { #[derive(Builder, Debug, PartialEq)]
pub struct QueryContainerOpts<'a> {
#[builder(setter(into, strip_option))]
pub id: Option<ContainerId>, pub id: Option<ContainerId>,
#[builder(setter(into, strip_option))]
pub platform: Option<Platform>, pub platform: Option<Platform>,
} }
pub struct QueryDirectoryOpts { #[derive(Builder, Debug, PartialEq)]
pub struct QueryDirectoryOpts<'a> {
#[builder(setter(into, strip_option))]
pub id: Option<DirectoryId>, pub id: Option<DirectoryId>,
} }
pub struct QueryGitOpts { #[derive(Builder, Debug, PartialEq)]
pub struct QueryGitOpts<'a> {
#[builder(setter(into, strip_option))]
pub keep_git_dir: Option<bool>, pub keep_git_dir: Option<bool>,
} }
pub struct QueryPipelineOpts { #[derive(Builder, Debug, PartialEq)]
pub description: Option<String>, pub struct QueryPipelineOpts<'a> {
#[builder(setter(into, strip_option))]
pub description: Option<&'a str>,
} }
pub struct QuerySocketOpts { #[derive(Builder, Debug, PartialEq)]
pub struct QuerySocketOpts<'a> {
#[builder(setter(into, strip_option))]
pub id: Option<SocketId>, pub id: Option<SocketId>,
} }
impl Query { impl Query {
pub fn cache_volume(&self, key: String) -> CacheVolume { pub fn cache_volume(&self, key: impl Into<String>) -> CacheVolume {
let mut query = self.selection.select("cacheVolume"); let mut query = self.selection.select("cacheVolume");
query = query.arg("key", key); query = query.arg("key", key.into());
return CacheVolume { return CacheVolume {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1341,10 +1448,10 @@ impl Query {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn git(&self, url: String, opts: Option<QueryGitOpts>) -> GitRepository { pub fn git(&self, url: impl Into<String>, opts: Option<QueryGitOpts>) -> GitRepository {
let mut query = self.selection.select("git"); let mut query = self.selection.select("git");
query = query.arg("url", url); query = query.arg("url", url.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(keep_git_dir) = opts.keep_git_dir { if let Some(keep_git_dir) = opts.keep_git_dir {
query = query.arg("keepGitDir", keep_git_dir); query = query.arg("keepGitDir", keep_git_dir);
@ -1366,10 +1473,10 @@ impl Query {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn http(&self, url: String) -> File { pub fn http(&self, url: impl Into<String>) -> File {
let mut query = self.selection.select("http"); let mut query = self.selection.select("http");
query = query.arg("url", url); query = query.arg("url", url.into());
return File { return File {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1377,10 +1484,10 @@ impl Query {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn pipeline(&self, name: String, opts: Option<QueryPipelineOpts>) -> Query { pub fn pipeline(&self, name: impl Into<String>, opts: Option<QueryPipelineOpts>) -> Query {
let mut query = self.selection.select("pipeline"); let mut query = self.selection.select("pipeline");
query = query.arg("name", name); query = query.arg("name", name.into());
if let Some(opts) = opts { if let Some(opts) = opts {
if let Some(description) = opts.description { if let Some(description) = opts.description {
query = query.arg("description", description); query = query.arg("description", description);
@ -1393,10 +1500,10 @@ impl Query {
conn: self.conn.clone(), conn: self.conn.clone(),
}; };
} }
pub fn project(&self, name: String) -> Project { pub fn project(&self, name: impl Into<String>) -> Project {
let mut query = self.selection.select("project"); let mut query = self.selection.select("project");
query = query.arg("name", name); query = query.arg("name", name.into());
return Project { return Project {
proc: self.proc.clone(), proc: self.proc.clone(),
@ -1462,7 +1569,7 @@ impl Socket {
query.execute(&graphql_client(&self.conn)) query.execute(&graphql_client(&self.conn))
} }
} }
#[derive(Serialize)] #[derive(Serialize, Clone, PartialEq, Debug)]
pub enum CacheSharingMode { pub enum CacheSharingMode {
SHARED, SHARED,
PRIVATE, PRIVATE,

View File

@ -1,19 +1,18 @@
use dagger_sdk::{connect, ContainerExecOpts}; use dagger_sdk::{connect, ContainerExecOptsBuilder};
#[test] #[test]
fn test_example_container() { fn test_example_container() {
let client = connect().unwrap(); let client = connect().unwrap();
let alpine = client.container(None).from("alpine:3.16.2".into()); let alpine = client.container(None).from("alpine:3.16.2");
let out = alpine let out = alpine
.exec(Some(ContainerExecOpts { .exec(Some(
args: Some(vec!["cat".into(), "/etc/alpine-release".into()]), ContainerExecOptsBuilder::default()
stdin: None, .args(vec!["cat", "/etc/alpine-release"])
redirect_stdout: None, .build()
redirect_stderr: None, .unwrap(),
experimental_privileged_nesting: None, ))
}))
.stdout() .stdout()
.unwrap(); .unwrap();