1use std::ffi::OsString;
2
3use crate::{Defaults, MagicSignature, SearchMode};
4
5pub mod from_environment {
7 #[derive(Debug, thiserror::Error)]
9 #[allow(missing_docs)]
10 pub enum Error {
11 #[error(transparent)]
12 ParseValue(#[from] gix_config_value::Error),
13 #[error("Glob and no-glob settings are mutually exclusive")]
14 MixedGlobAndNoGlob,
15 }
16}
17
18impl Defaults {
19 pub fn from_environment(var: &mut dyn FnMut(&str) -> Option<OsString>) -> Result<Self, from_environment::Error> {
32 let mut env_bool = |name: &str| -> Result<Option<bool>, gix_config_value::Error> {
33 var(name)
34 .map(|val| gix_config_value::Boolean::try_from(val).map(|b| b.0))
35 .transpose()
36 };
37
38 let literal = env_bool("GIT_LITERAL_PATHSPECS")?.unwrap_or_default();
39 let signature = env_bool("GIT_ICASE_PATHSPECS")?
40 .and_then(|val| val.then_some(MagicSignature::ICASE))
41 .unwrap_or_default();
42 if literal {
43 return Ok(Defaults {
44 signature,
45 search_mode: SearchMode::Literal,
46 literal,
47 });
48 }
49 let glob = env_bool("GIT_GLOB_PATHSPECS")?;
50 let mut search_mode = glob
51 .and_then(|glob| glob.then_some(SearchMode::PathAwareGlob))
52 .unwrap_or_default();
53 search_mode = env_bool("GIT_NOGLOB_PATHSPECS")?
54 .map(|no_glob| {
55 if glob.unwrap_or_default() && no_glob {
56 Err(from_environment::Error::MixedGlobAndNoGlob)
57 } else {
58 Ok(SearchMode::Literal)
59 }
60 })
61 .transpose()?
62 .unwrap_or(search_mode);
63
64 Ok(Defaults {
65 signature,
66 search_mode,
67 literal,
68 })
69 }
70}