#![deny(rust_2018_idioms, missing_docs)]
#![forbid(unsafe_code)]
use std::{borrow::Cow, collections::BTreeMap};
#[derive(Clone)]
pub struct File {
config: gix_config::File<'static>,
}
mod access;
pub mod config;
pub mod is_active_platform;
pub struct IsActivePlatform {
pub(crate) search: Option<gix_pathspec::Search>,
}
impl File {
pub fn append_submodule_overrides(&mut self, config: &gix_config::File<'_>) -> &mut Self {
let mut values = BTreeMap::<_, Vec<_>>::new();
for (module_name, section) in config
.sections_by_name("submodule")
.into_iter()
.flatten()
.filter_map(|s| s.header().subsection_name().map(|n| (n, s)))
{
for field in ["url", "fetchRecurseSubmodules", "ignore", "update", "branch"] {
if let Some(value) = section.value(field) {
values.entry((module_name, field)).or_default().push(value);
}
}
}
let values = {
let mut v: Vec<_> = values.into_iter().collect();
v.sort_by_key(|a| a.0 .0);
v
};
let mut config_to_append = gix_config::File::new(config.meta_owned());
let mut prev_name = None;
for ((module_name, field), values) in values {
if prev_name != Some(module_name) {
config_to_append
.new_section("submodule", Some(Cow::Owned(module_name.to_owned())))
.expect("all names come from valid configuration, so remain valid");
prev_name = Some(module_name);
}
config_to_append
.section_mut("submodule", Some(module_name))
.expect("always set at this point")
.push(
field.try_into().expect("statically known key"),
Some(values.last().expect("at least one value or we wouldn't be here")),
);
}
self.config.append(config_to_append);
self
}
}
mod init {
use std::path::PathBuf;
use crate::File;
impl std::fmt::Debug for File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("File")
.field("config_path", &self.config_path())
.field("config", &format_args!("r#\"{}\"#", self.config))
.finish()
}
}
pub(crate) const META_MARKER: gix_config::Source = gix_config::Source::Api;
impl File {
pub fn from_bytes(
bytes: &[u8],
path: impl Into<Option<PathBuf>>,
config: &gix_config::File<'_>,
) -> Result<Self, gix_config::parse::Error> {
let metadata = {
let mut meta = gix_config::file::Metadata::from(META_MARKER);
meta.path = path.into();
meta
};
let modules = gix_config::File::from_parse_events_no_includes(
gix_config::parse::Events::from_bytes_owned(bytes, None)?,
metadata,
);
let mut res = Self { config: modules };
res.append_submodule_overrides(config);
Ok(res)
}
pub fn into_config(self) -> gix_config::File<'static> {
self.config
}
}
}