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