tq/
lib.rs

1use std::{fs::File, io::Read};
2use thiserror::Error;
3use toml::Value;
4
5type TqResult<T> = std::result::Result<T, TqError>;
6
7#[derive(Error, Debug)]
8pub enum TqError {
9    #[error("Failed to open file \"{file_name}\": {cause}")]
10    FileOpenError { file_name: String, cause: String },
11
12    #[error("Failed to parse TOML file \"{file_name}\": {cause}")]
13    TomlParseError { file_name: String, cause: String },
14
15    #[error("Could not find pattern {pattern}")]
16    PatternNotFoundError { pattern: String },
17}
18
19pub fn extract_pattern<'a>(toml_file: &'a Value, pattern: &str) -> TqResult<&'a Value> {
20    if pattern.is_empty() || pattern == "." {
21        return Ok(toml_file);
22    }
23
24    let pattern = pattern.trim_start_matches('.');
25
26    pattern
27        .split('.')
28        .fold(Some(toml_file), |acc, key| match acc {
29            Some(a) => a.get(key),
30            None => None,
31        })
32        .ok_or_else(|| TqError::PatternNotFoundError {
33            pattern: pattern.to_string(),
34        })
35}
36
37#[deprecated = 
38    "Users should use/call the similar functions from the `toml` crate going forward. This function will be \
39    removed in a future release"
40]
41pub fn load_toml_from_file(file_name: &str) -> TqResult<toml::Value> {
42    let mut file = File::open(file_name).map_err(|e| TqError::FileOpenError {
43        file_name: file_name.to_string(),
44        cause: e.to_string(),
45    })?;
46    let mut contents = String::new();
47    let _ = file.read_to_string(&mut contents);
48    toml::from_str::<Value>(&contents).map_err(|e| TqError::TomlParseError {
49        file_name: file_name.to_string(),
50        cause: e.to_string(),
51    })
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_extract_pattern() {
60        let toml_file = toml::from_str(
61            r#"
62            [package]
63            test = "test"
64            "#,
65        )
66        .unwrap();
67
68        let x = extract_pattern(&toml_file, "package.test").unwrap();
69
70        assert_eq!(x, &Value::String("test".to_string()));
71    }
72
73    #[test]
74    fn test_fail_extract() {
75        let toml_file = toml::from_str(
76            r#"
77            [package]
78            test = "test"
79            "#,
80        )
81        .unwrap();
82
83        let x = extract_pattern(&toml_file, "package.test2");
84
85        assert!(x.is_err());
86        assert_eq!(
87            x.unwrap_err().to_string(),
88            "Could not find pattern package.test2"
89        );
90    }
91
92    #[test]
93    fn test_get_prop_with_many_tables() {
94        let toml_file = toml::from_str(
95            r#"
96            [package]
97            test = "test"
98            [package2]
99            test2 = "test2"
100            "#,
101        )
102        .unwrap();
103
104        let x = extract_pattern(&toml_file, "package.test").unwrap();
105
106        assert_eq!(x, &Value::String("test".to_string()));
107    }
108}