gix_config/file/init/
from_env.rs1use bstr::ByteSlice;
2
3use crate::{File, KeyRef, file, file::init, parse::section, path::interpolate};
4
5#[derive(Debug, thiserror::Error)]
7#[expect(missing_docs)]
8pub enum Error {
9 #[error("Configuration {kind} at index {index} contained illformed UTF-8")]
10 IllformedUtf8 { index: usize, kind: &'static str },
11 #[error("GIT_CONFIG_COUNT was not a positive integer: {}", .input)]
12 InvalidConfigCount { input: String },
13 #[error("GIT_CONFIG_KEY_{} was not set", .key_id)]
14 InvalidKeyId { key_id: usize },
15 #[error("GIT_CONFIG_KEY_{} was set to an invalid value: {}", .key_id, .key_val)]
16 InvalidKeyValue { key_id: usize, key_val: String },
17 #[error("GIT_CONFIG_VALUE_{} was not set", .value_id)]
18 InvalidValueId { value_id: usize },
19 #[error(transparent)]
20 PathInterpolationError(#[from] interpolate::Error),
21 #[error(transparent)]
22 Includes(#[from] init::includes::Error),
23 #[error(transparent)]
24 Section(#[from] section::header::Error),
25 #[error(transparent)]
26 SectionValue(#[from] file::section::value::Error),
27}
28
29impl File {
31 pub fn from_env(options: init::Options<'_>) -> Result<Option<File>, Error> {
38 use std::env;
39 let count: usize = match env::var("GIT_CONFIG_COUNT") {
40 Ok(v) => v.parse().map_err(|_| Error::InvalidConfigCount { input: v })?,
41 Err(_) => return Ok(None),
42 };
43
44 if count == 0 {
45 return Ok(None);
46 }
47
48 let meta = file::Metadata {
49 path: None,
50 source: crate::Source::Env,
51 level: 0,
52 trust: gix_sec::Trust::Full,
53 };
54 let mut config = File::new(meta);
55 for i in 0..count {
56 let key = gix_path::os_string_into_bstring(
57 env::var_os(format!("GIT_CONFIG_KEY_{i}")).ok_or(Error::InvalidKeyId { key_id: i })?,
58 )
59 .map_err(|_| Error::IllformedUtf8 { index: i, kind: "key" })?;
60 let value = env::var_os(format!("GIT_CONFIG_VALUE_{i}")).ok_or(Error::InvalidValueId { value_id: i })?;
61 let key = KeyRef::parse_unvalidated(key.as_ref()).ok_or_else(|| Error::InvalidKeyValue {
62 key_id: i,
63 key_val: key.to_string(),
64 })?;
65
66 config
67 .section_mut_or_create_new_inner(key.section_name, key.subsection_name)?
68 .push(
69 key.value_name,
70 Some(
71 gix_path::os_str_into_bstr(&value)
72 .map_err(|_| Error::IllformedUtf8 {
73 index: i,
74 kind: "value",
75 })?
76 .as_bytes()
77 .into(),
78 ),
79 )?;
80 }
81
82 let mut buf = Vec::new();
83 init::includes::resolve(&mut config, &mut buf, options)?;
84 Ok(Some(config))
85 }
86}