arcbox_docker_tools/
lockfile.rs1use std::collections::HashMap;
9
10use serde::Deserialize;
11
12#[derive(Debug, Deserialize)]
14pub struct AssetsLock {
15 #[serde(default)]
16 pub tools: Vec<ToolEntry>,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
27#[serde(rename_all = "lowercase")]
28pub enum ToolGroup {
29 Docker,
30 Kubernetes,
31 Desktop,
32}
33
34#[derive(Debug, Clone, Deserialize)]
36pub struct ArchEntry {
37 pub sha256: String,
38}
39
40#[derive(Debug, Clone, Deserialize)]
42pub struct ToolEntry {
43 pub name: String,
44 pub group: ToolGroup,
45 pub version: String,
46 #[serde(default)]
47 pub arch: HashMap<String, ArchEntry>,
48}
49
50impl ToolEntry {
51 #[must_use]
53 pub fn sha256_for_arch(&self, arch: &str) -> Option<&str> {
54 let key = match arch {
56 "aarch64" => "arm64",
57 "amd64" => "x86_64",
58 _ => arch,
59 };
60 self.arch.get(key).map(|e| e.sha256.as_str())
61 }
62}
63
64pub fn parse_tools(lock_toml: &str) -> Result<Vec<ToolEntry>, toml::de::Error> {
66 let lock: AssetsLock = toml::from_str(lock_toml)?;
67 Ok(lock.tools)
68}
69
70pub fn parse_tools_for_group(
72 lock_toml: &str,
73 group: ToolGroup,
74) -> Result<Vec<ToolEntry>, toml::de::Error> {
75 Ok(parse_tools(lock_toml)?
76 .into_iter()
77 .filter(|tool| tool.group == group)
78 .collect())
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 const SAMPLE: &str = r#"
86[boot]
87version = "0.5.1"
88cdn = "https://boot.arcboxcdn.com"
89
90[[tools]]
91name = "docker"
92group = "docker"
93version = "29.3.1"
94arch.arm64.sha256 = "aaa"
95arch.x86_64.sha256 = "bbb"
96
97[[tools]]
98name = "docker-buildx"
99group = "docker"
100version = "0.21.1"
101arch.arm64.sha256 = "ccc"
102
103[[tools]]
104name = "kubectl"
105group = "kubernetes"
106version = "1.35.3"
107arch.arm64.sha256 = "ddd"
108
109[[tools]]
110name = "pstramp"
111group = "desktop"
112version = "0.2.0"
113arch.arm64.sha256 = "eee"
114"#;
115
116 #[test]
117 fn parse_tool_entries() {
118 let tools = parse_tools(SAMPLE).unwrap();
119 assert_eq!(tools.len(), 4);
120 assert_eq!(tools[0].name, "docker");
121 assert_eq!(tools[0].group, ToolGroup::Docker);
122 assert_eq!(tools[0].version, "29.3.1");
123 assert_eq!(tools[0].sha256_for_arch("arm64"), Some("aaa"));
124 assert_eq!(tools[0].sha256_for_arch("x86_64"), Some("bbb"));
125 assert_eq!(tools[1].sha256_for_arch("x86_64"), None);
126 }
127
128 #[test]
129 fn parse_tools_for_specific_group() {
130 let docker_tools = parse_tools_for_group(SAMPLE, ToolGroup::Docker).unwrap();
131 assert_eq!(docker_tools.len(), 2);
132 assert!(
133 docker_tools
134 .iter()
135 .all(|tool| tool.group == ToolGroup::Docker)
136 );
137
138 let kubernetes_tools = parse_tools_for_group(SAMPLE, ToolGroup::Kubernetes).unwrap();
139 assert_eq!(kubernetes_tools.len(), 1);
140 assert_eq!(kubernetes_tools[0].name, "kubectl");
141
142 let desktop_tools = parse_tools_for_group(SAMPLE, ToolGroup::Desktop).unwrap();
145 assert_eq!(desktop_tools.len(), 1);
146 assert_eq!(desktop_tools[0].name, "pstramp");
147 }
148
149 #[test]
150 fn arch_aliases() {
151 let tools = parse_tools(SAMPLE).unwrap();
152 assert_eq!(tools[0].sha256_for_arch("aarch64"), Some("aaa"));
154 assert_eq!(tools[0].sha256_for_arch("amd64"), Some("bbb"));
156 }
157}