libgir/config/
external_libraries.rs

1use std::str::FromStr;
2
3use super::error::*;
4use crate::{nameutil::crate_name, version::Version};
5
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct ExternalLibrary {
8    pub namespace: String,
9    pub crate_name: String,
10    pub lib_name: String,
11    pub min_version: Option<Version>,
12}
13
14pub fn read_external_libraries(toml: &toml::Value) -> Result<Vec<ExternalLibrary>, String> {
15    let mut external_libraries = match toml.lookup("options.external_libraries") {
16        Some(a) => a
17            .as_result_vec("options.external_libraries")?
18            .iter()
19            .filter_map(|v| v.as_str().map(String::from))
20            .map(|namespace| {
21                let crate_name_ = crate_name(&namespace);
22                ExternalLibrary {
23                    crate_name: crate_name_.clone(),
24                    lib_name: crate_name_,
25                    min_version: None,
26                    namespace,
27                }
28            })
29            .collect(),
30        None => Vec::new(),
31    };
32    let custom_libs = toml
33        .lookup("external_libraries")
34        .and_then(toml::Value::as_table);
35    if let Some(custom_libs) = custom_libs {
36        for custom_lib in custom_libs {
37            if let Some(info) = custom_lib.1.as_table() {
38                let namespace = custom_lib.0.as_str();
39                let crate_name_ = info.get("crate").map_or_else(
40                    || crate_name(namespace),
41                    |c| c.as_str().expect("crate name must be a string").to_string(),
42                );
43                let min_version = info
44                    .get("min_version")
45                    .map(|v| v.as_str().expect("min required version must be a string"))
46                    .map(|v| Version::from_str(v).expect("Invalid version number"));
47                let lib = ExternalLibrary {
48                    namespace: namespace.to_owned(),
49                    crate_name: crate_name_,
50                    lib_name: crate_name(namespace),
51                    min_version,
52                };
53                external_libraries.push(lib);
54            } else if let Some(namespace) = custom_lib.1.as_str() {
55                let crate_name_ = custom_lib.0;
56                let lib = ExternalLibrary {
57                    namespace: namespace.to_owned(),
58                    crate_name: crate_name_.clone(),
59                    lib_name: crate_name(custom_lib.1.as_str().expect("No custom lib name set")),
60                    min_version: None,
61                };
62                external_libraries.push(lib);
63            } else {
64                return Err(format!(
65                    "For external library \"{:#?}\" namespace must be string or a table",
66                    custom_lib.0
67                ));
68            }
69        }
70    }
71
72    Ok(external_libraries)
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    fn toml(input: &str) -> ::toml::Value {
80        let value = ::toml::from_str(input);
81        assert!(value.is_ok());
82        value.unwrap()
83    }
84
85    #[test]
86    fn test_read_external_libraries() {
87        let toml = toml(
88            r#"
89[options]
90external_libraries = [
91   "GLib",
92   "Gdk",
93   "GdkPixbuf",
94]
95
96[external_libraries]
97coollib="CoolLib"
98other-lib="OtherLib"
99"#,
100        );
101        let libs = read_external_libraries(&toml).unwrap();
102
103        assert_eq!(
104            libs[0],
105            ExternalLibrary {
106                namespace: "GLib".to_owned(),
107                crate_name: "glib".to_owned(),
108                lib_name: "glib".to_owned(),
109                min_version: None,
110            }
111        );
112        assert_eq!(
113            libs[1],
114            ExternalLibrary {
115                namespace: "Gdk".to_owned(),
116                crate_name: "gdk".to_owned(),
117                lib_name: "gdk".to_owned(),
118                min_version: None,
119            }
120        );
121        assert_eq!(
122            libs[2],
123            ExternalLibrary {
124                namespace: "GdkPixbuf".to_owned(),
125                crate_name: "gdk_pixbuf".to_owned(),
126                lib_name: "gdk_pixbuf".to_owned(),
127                min_version: None,
128            }
129        );
130        // Sorted alphabetically
131        assert_eq!(
132            libs[3],
133            ExternalLibrary {
134                namespace: "CoolLib".to_owned(),
135                crate_name: "coollib".to_owned(),
136                lib_name: "cool_lib".to_owned(),
137                min_version: None,
138            }
139        );
140        assert_eq!(
141            libs[4],
142            ExternalLibrary {
143                namespace: "OtherLib".to_owned(),
144                crate_name: "other-lib".to_owned(),
145                lib_name: "other_lib".to_owned(),
146                min_version: None,
147            }
148        );
149    }
150
151    #[test]
152    fn test_read_external_libraries_with_min_version() {
153        let toml = toml(
154            r#"
155[external_libraries]
156CoolLib={crate = "coollib", min_version = "0.3.0"}
157OtherLib={min_version = "0.4.0"}
158"#,
159        );
160        let libs = read_external_libraries(&toml).unwrap();
161
162        // Sorted alphabetically
163        assert_eq!(
164            libs[0],
165            ExternalLibrary {
166                namespace: "CoolLib".to_owned(),
167                crate_name: "coollib".to_owned(),
168                lib_name: "cool_lib".to_owned(),
169                min_version: Some(Version::from_str("0.3.0").unwrap()),
170            }
171        );
172        assert_eq!(
173            libs[1],
174            ExternalLibrary {
175                namespace: "OtherLib".to_owned(),
176                crate_name: "other_lib".to_owned(),
177                lib_name: "other_lib".to_owned(),
178                min_version: Some(Version::from_str("0.4.0").unwrap()),
179            }
180        );
181    }
182}