1pub mod clapget;
34pub mod convert;
35pub mod env;
36pub mod grabber;
37pub mod prelude;
38pub mod replace;
39pub mod tomlget;
40
41use crate::convert::Holder;
42use crate::convert::Localizer;
43use crate::replace::replace_env;
44use std::path::PathBuf;
45
46pub use clap::{clap_app, crate_version, ArgMatches, Values};
47
48pub fn clap_env<'a, G: Getter<'a>>(a: G) -> Holder<env::Enver, G>
49where
50 String: From<G::Out>,
51{
52 env::Enver {}.hold(a)
54}
55
56pub fn with_toml_env<'a, G, S, IT>(
57 a: G,
58 it: IT,
59) -> Holder<Holder<env::Enver, G>, Localizer<toml::Value>>
60where
61 G: Getter<'a, Out = &'a str>,
62 S: AsRef<str>,
63 IT: IntoIterator<Item = S>,
64{
65 let tml = tomlget::load_first_toml(a.value("config", Filter::Arg), it)
66 .unwrap_or(Localizer::new(toml::Value::Boolean(false), ""));
67 env::Enver {}.hold(a).hold(tml)
68}
69
70#[derive(Clone, Copy, Debug, PartialEq)]
71pub enum Filter {
72 Conf,
73 Arg,
74 Env,
75 Other(char),
76}
77
78pub trait Getter<'a>: Sized {
79 type Iter: Iterator<Item = Self::Out>;
80 type Out: PartialEq + std::fmt::Debug + std::fmt::Display;
81 fn value<S: AsRef<str>>(&self, s: S, f: Filter) -> Option<Self::Out>;
82 fn values<S: AsRef<str>>(&self, s: S, f: Filter) -> Option<Self::Iter>;
83
84 fn local_value<S: AsRef<str>>(&self, s: S, f: Filter) -> Option<PathBuf> {
85 let v = self.value(s, f)?;
86 let s = replace_env(&v.to_string()).ok()?;
87 Some(PathBuf::from(s))
88 }
89
90 fn bool_flag<S: AsRef<str>>(&self, s: S, f: Filter) -> bool {
91 self.value(s, f).is_some()
92 }
93
94 fn sub<S: AsRef<str>>(&self, _: S, _: Filter) -> bool {
95 return false;
96 }
97
98 fn wrap<R2, F: Fn(Self::Out) -> R2>(self, f: F) -> convert::Wrapper<Self, F> {
99 convert::Wrapper::new(self, f)
100 }
101
102 fn hold<B>(self, b: B) -> convert::Holder<Self, B>
103 where
104 B: Getter<'a>,
105 Self::Out: std::convert::From<B::Out>,
106 B::Out: PartialEq + std::fmt::Debug + std::fmt::Display,
107 {
108 convert::Holder::new(self, b)
109 }
110
111 fn grab(&'a self) -> grabber::Grabber<'a, Self> {
112 grabber::Grabber::new(self)
113 }
114
115 fn grab_local(&'a self) -> grabber::LocalGrabber<'a, Self> {
116 grabber::LocalGrabber::new(self)
117 }
118
119 fn grab_multi(&'a self) -> grabber::MultiGrabber<'a, Self> {
120 grabber::MultiGrabber::new(self)
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 #[test]
128 fn try_holder() {
129 let a = ArgMatches::new();
130 let tml: toml::Value = "[a]\ncar=\"red\"".parse().unwrap();
131 let ce = clap_env(&a).hold(tml);
133 assert_eq!(ce.value("ss", Filter::Arg), None);
137 assert_eq!(
138 ce.value("PWD", Filter::Env),
139 Some("/home/matthew/scripts/rust/mlibs/clap_conf".to_string())
140 );
141
142 assert_eq!(
143 ce.grab().env("PWD").done(),
144 Some("/home/matthew/scripts/rust/mlibs/clap_conf".to_string())
145 );
146
147 assert_eq!(ce.grab().conf("a.car").done(), Some("red".to_string()));
148
149 }
155
156 #[test]
157 fn test_grab() {
158 let a = ArgMatches::new();
159 let r = with_toml_env(&a, &["test_data/test1.toml"]);
160 assert_eq!(r.grab().conf("a.b.c").done(), Some("hello".to_string()));
161 }
162}