1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::fmt::Display;
4use std::path::PathBuf;
5use std::str::FromStr;
6use winnow::ascii::alpha1;
7use winnow::combinator::alt;
8use winnow::combinator::delimited;
9use winnow::combinator::opt;
10use winnow::combinator::peek;
11use winnow::combinator::repeat;
12use winnow::error::IResult;
13use winnow::stream::AsChar;
14use winnow::token::take_while;
15use winnow::PResult;
16use winnow::Parser;
17mod variable;
18use eyre::Result;
19use serde::de::{self, Deserializer, Visitor};
20use serde::ser::Serializer;
21use thiserror::Error;
22use variable::parse_variable;
23use variable::Variable;
24
25pub mod environment;
26use environment::Environment;
27use environment::EnvironmentBuilder;
28
29mod varpath;
30use varpath::PathPart;
31pub use varpath::VarPath;
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use homedir::my_home;
37 use pretty_assertions::assert_eq;
38
39 #[test]
40 fn test_no_lookup() {
41 let env = EnvironmentBuilder::default().build();
42 let actual = VarPath::from_str("/a/b/c").unwrap().eval(&env).unwrap();
43 let expected = PathBuf::from("/a/b/c");
44 assert_eq!(expected, actual);
45 }
46
47 #[test]
48 fn test_lookup_no_braces() {
49 let key = String::from("key");
50 let value = String::from("b");
51 let env = EnvironmentBuilder::default().set(&key, &value).build();
52 let actual = VarPath::from_str("/a/$key/c").unwrap().eval(&env).unwrap();
53 let expected = PathBuf::from("/a/b/c");
54 assert_eq!(expected, actual);
55 }
56
57 #[test]
58 fn test_lookup_braces() {
59 let key = String::from("key");
60 let value = String::from("b");
61 let env = EnvironmentBuilder::default().set(&key, &value).build();
62 let actual = VarPath::from_str("/a/${key}/c")
63 .unwrap()
64 .eval(&env)
65 .unwrap();
66 let expected = PathBuf::from("/a/b/c");
67 assert_eq!(expected, actual);
68 }
69
70 #[test]
71 fn test_process_env() {
72 let input = "/a/${PWD}/c";
73 let env = EnvironmentBuilder::default().with_process_env().build();
74 let actual = VarPath::from_str(input).unwrap().eval(&env).unwrap();
75 assert_ne!(PathBuf::from(input), actual);
76 }
77
78 #[test]
79 fn test_undefined_var() {
80 let env = EnvironmentBuilder::default().build();
81 let result = VarPath::from_str("/a/${BAD_BAD_BAD}/c").unwrap().eval(&env);
82 assert!(result.is_err());
83 }
84
85 #[test]
86 fn test_home() {
87 let input = "${HOME}";
88 let env = EnvironmentBuilder::default().with_process_env().build();
89 let actual = VarPath::from_str(input).unwrap().eval(&env).unwrap();
90 let expected = homedir::my_home().unwrap().unwrap();
91 assert_eq!(expected, actual);
92 }
93}