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}