1use std::collections::BTreeMap;
2
3use serde::Deserialize;
4
5#[derive(Debug, Deserialize)]
6pub struct CargoToml {
7 pub dependencies: Option<BTreeMap<String, Dependency>>,
8}
9
10#[derive(Debug, Deserialize)]
11pub struct Dependency {
12 pub version: String,
13}
14
15impl CargoToml {
16 pub fn get_dependency(&self, name: &str) -> Option<&Dependency> {
17 self.dependencies.as_ref().and_then(|deps| deps.get(name))
18 }
19}
20
21pub fn parse_cargo_toml(toml: &str) -> Result<CargoToml, String> {
22 #[derive(Deserialize)]
23 struct CargoTomlVisitor {
24 dependencies: Option<BTreeMap<String, toml::Value>>,
25 }
26
27 let parsed = toml::from_str::<CargoTomlVisitor>(toml).map_err(|e| e.to_string())?;
28
29 let dependencies = parsed
30 .dependencies
31 .map(parse_dependencies)
32 .map_or(Ok(None), |v| v.map(Some))?;
33
34 Ok(CargoToml { dependencies })
35}
36
37fn parse_dependencies(
38 deps: BTreeMap<String, toml::Value>,
39) -> Result<BTreeMap<String, Dependency>, String> {
40 let mut dependencies = BTreeMap::new();
41 for (name, value) in deps {
42 if value.is_str() {
43 let version = value.as_str().unwrap();
44 dependencies.insert(
45 name,
46 Dependency {
47 version: version.to_string(),
48 },
49 );
50 } else if value.is_table() {
51 if let Some(version) = value.get("version") {
52 dependencies.insert(
53 name,
54 Dependency {
55 version: version
56 .as_str()
57 .ok_or("can't parse version as str".to_string())?
58 .to_string(),
59 },
60 );
61 } else if let Some(tag) = value.get("tag") {
62 dependencies.insert(
63 name,
64 Dependency {
65 version: tag
66 .as_str()
67 .ok_or("can't parse tag as str".to_string())?
68 .to_string(),
69 },
70 );
71 }
72 }
73 }
74 Ok(dependencies)
75}
76
77#[cfg(test)]
78mod test {
79 use super::*;
80 #[test]
81 fn test_parse_cargo_toml() {
82 let toml = r#"
83 [package]
84 name = "hello"
85 version = "0.1.0"
86 [dependencies]
87 serde = "1.0"
88 toml = { version = "0.5" }
89 hyle = { git = "https://github.com/Hyle-org/hyle", tag = "0.12" }
90 "#;
91 let cargo_toml = parse_cargo_toml(toml).unwrap();
92 assert_eq!(cargo_toml.dependencies.as_ref().unwrap().len(), 3);
93
94 assert_eq!(cargo_toml.get_dependency("serde").unwrap().version, "1.0");
95 assert_eq!(cargo_toml.get_dependency("toml").unwrap().version, "0.5");
96 assert_eq!(cargo_toml.get_dependency("hyle").unwrap().version, "0.12");
97 }
98}
99