1use std::collections::HashMap;
11
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase", default)]
17pub struct ImageSpec {
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub base: Option<BaseImage>,
21 #[serde(skip_serializing_if = "Vec::is_empty")]
23 pub build_steps: Vec<ImageBuildStep>,
24 #[serde(skip_serializing_if = "HashMap::is_empty")]
26 pub env: HashMap<String, String>,
27 #[serde(skip_serializing_if = "ImageArchitecture::is_unspecified")]
29 pub architecture: ImageArchitecture,
30 #[serde(skip_serializing_if = "String::is_empty")]
32 pub python_version: String,
33}
34
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
37pub enum BaseImage {
38 #[default]
40 #[serde(rename = "BASE_IMAGE_UNSPECIFIED")]
41 Unspecified,
42 #[serde(rename = "BASE_IMAGE_DEBIAN")]
44 Debian,
45}
46
47#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
49pub enum ImageArchitecture {
50 #[default]
52 #[serde(rename = "IMAGE_ARCHITECTURE_UNSPECIFIED")]
53 Unspecified,
54 #[serde(rename = "IMAGE_ARCHITECTURE_AMD64")]
56 Amd64,
57 #[serde(rename = "IMAGE_ARCHITECTURE_ARM64")]
59 Arm64,
60}
61
62impl ImageArchitecture {
63 #[allow(clippy::trivially_copy_pass_by_ref)]
65 fn is_unspecified(&self) -> bool {
66 matches!(self, ImageArchitecture::Unspecified)
67 }
68}
69
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub enum ImageBuildStep {
74 AptInstall(PackageInstall),
76 PipInstall(PackageInstall),
78 RunCommand(RunCommand),
80 AddLocalFile(AddLocalFile),
82 AddLocalDir(AddLocalDir),
84}
85
86#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
88#[serde(default)]
89pub struct PackageInstall {
90 #[serde(skip_serializing_if = "Vec::is_empty")]
92 pub packages: Vec<String>,
93}
94
95#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
97#[serde(default)]
98pub struct RunCommand {
99 #[serde(skip_serializing_if = "String::is_empty")]
101 pub command: String,
102}
103
104#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
106#[serde(rename_all = "camelCase", default)]
107pub struct AddLocalFile {
108 #[serde(skip_serializing_if = "String::is_empty")]
110 pub content_sha256: String,
111 #[serde(skip_serializing_if = "String::is_empty")]
113 pub remote_path: String,
114 #[serde(skip_serializing_if = "is_zero")]
116 pub mode: u32,
117}
118
119#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
121#[serde(rename_all = "camelCase", default)]
122pub struct AddLocalDir {
123 #[serde(skip_serializing_if = "String::is_empty")]
125 pub remote_path: String,
126 #[serde(skip_serializing_if = "Vec::is_empty")]
128 pub files: Vec<AddLocalDirFile>,
129}
130
131#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
133#[serde(rename_all = "camelCase", default)]
134pub struct AddLocalDirFile {
135 #[serde(skip_serializing_if = "String::is_empty")]
137 pub relative_path: String,
138 #[serde(skip_serializing_if = "String::is_empty")]
140 pub content_sha256: String,
141 #[serde(skip_serializing_if = "is_zero")]
143 pub mode: u32,
144}
145
146#[allow(clippy::trivially_copy_pass_by_ref)]
148fn is_zero(n: &u32) -> bool {
149 *n == 0
150}