Skip to main content

a3s_box_sdk/client/
builders.rs

1/// Fluent OCI image builder backed by the local runtime build engine.
2#[derive(Debug, Clone)]
3pub struct ImageBuilder {
4    client: A3sBoxClient,
5    request: BuildImage,
6}
7
8impl ImageBuilder {
9    fn new(client: A3sBoxClient, context_dir: impl Into<PathBuf>) -> Self {
10        Self {
11            client,
12            request: BuildImage::new(context_dir),
13        }
14    }
15
16    /// Select a Dockerfile. Relative paths are resolved from the build context.
17    pub fn dockerfile(mut self, path: impl Into<PathBuf>) -> Self {
18        let path = path.into();
19        self.request.dockerfile_path = if path.is_relative() {
20            self.request.context_dir.join(path)
21        } else {
22            path
23        };
24        self
25    }
26
27    pub fn tag(mut self, tag: impl Into<String>) -> Self {
28        self.request.tag = Some(tag.into());
29        self
30    }
31
32    pub fn build_arg(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
33        self.request.build_args.insert(key.into(), value.into());
34        self
35    }
36
37    pub const fn quiet(mut self, quiet: bool) -> Self {
38        self.request.quiet = quiet;
39        self
40    }
41
42    pub fn platform(mut self, platform: Platform) -> Self {
43        self.request.platforms.push(platform);
44        self
45    }
46
47    pub fn target(mut self, target: impl Into<String>) -> Self {
48        self.request.target = Some(target.into());
49        self
50    }
51
52    pub const fn no_cache(mut self, no_cache: bool) -> Self {
53        self.request.no_cache = no_cache;
54        self
55    }
56
57    pub fn request(&self) -> &BuildImage {
58        &self.request
59    }
60
61    pub async fn build(self) -> Result<BuildImageSummary> {
62        self.client.build_image(self.request).await
63    }
64}
65
66/// Fluent named-volume builder.
67#[derive(Debug, Clone)]
68pub struct VolumeBuilder {
69    client: A3sBoxClient,
70    request: CreateVolume,
71}
72
73impl VolumeBuilder {
74    fn new(client: A3sBoxClient, name: impl Into<String>) -> Self {
75        Self {
76            client,
77            request: CreateVolume::new(name),
78        }
79    }
80
81    pub fn label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
82        self.request.labels.insert(key.into(), value.into());
83        self
84    }
85
86    pub const fn size_limit(mut self, bytes: u64) -> Self {
87        self.request.size_limit = bytes;
88        self
89    }
90
91    pub fn request(&self) -> &CreateVolume {
92        &self.request
93    }
94
95    pub fn create(self) -> Result<VolumeSummary> {
96        self.client.create_volume(self.request)
97    }
98}
99
100/// Fluent bridge-network builder.
101#[derive(Debug, Clone)]
102pub struct NetworkBuilder {
103    client: A3sBoxClient,
104    request: CreateNetwork,
105}
106
107impl NetworkBuilder {
108    fn new(client: A3sBoxClient, name: impl Into<String>) -> Self {
109        Self {
110            client,
111            request: CreateNetwork::new(name),
112        }
113    }
114
115    pub fn subnet(mut self, subnet: impl Into<String>) -> Self {
116        self.request.subnet = subnet.into();
117        self
118    }
119
120    pub fn label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
121        self.request.labels.insert(key.into(), value.into());
122        self
123    }
124
125    pub const fn isolation(mut self, isolation: IsolationMode) -> Self {
126        self.request.isolation = isolation;
127        self
128    }
129
130    pub fn request(&self) -> &CreateNetwork {
131        &self.request
132    }
133
134    pub fn create(self) -> Result<NetworkSummary> {
135        self.client.create_network(self.request)
136    }
137}
138
139impl A3sBoxClient {
140    /// Start a fluent local OCI image build.
141    pub fn image(&self, context_dir: impl Into<PathBuf>) -> ImageBuilder {
142        ImageBuilder::new(self.clone(), context_dir)
143    }
144
145    /// Start a fluent named-volume creation request.
146    pub fn volume(&self, name: impl Into<String>) -> VolumeBuilder {
147        VolumeBuilder::new(self.clone(), name)
148    }
149
150    /// Start a fluent bridge-network creation request.
151    pub fn network(&self, name: impl Into<String>) -> NetworkBuilder {
152        NetworkBuilder::new(self.clone(), name)
153    }
154}