1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//! A high level wrapper around a single or multiple `git-config` file, for reading and mutation.
use std::{
borrow::Cow,
collections::HashMap,
ops::{Add, AddAssign},
path::PathBuf,
};
use bstr::BStr;
use gix_features::threading::OwnShared;
mod mutable;
pub use mutable::{multi_value::MultiValueMut, section::SectionMut, value::ValueMut};
///
#[allow(clippy::empty_docs)]
pub mod init;
mod access;
mod impls;
///
#[allow(clippy::empty_docs)]
pub mod includes;
mod meta;
mod util;
///
#[allow(clippy::empty_docs)]
pub mod section;
///
#[allow(clippy::empty_docs)]
pub mod rename_section {
/// The error returned by [`File::rename_section(…)`][crate::File::rename_section()].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
Lookup(#[from] crate::lookup::existing::Error),
#[error(transparent)]
Section(#[from] crate::parse::section::header::Error),
}
}
///
#[allow(clippy::empty_docs)]
pub mod set_raw_value {
/// The error returned by [`File::set_raw_value(…)`][crate::File::set_raw_value()].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
Header(#[from] crate::parse::section::header::Error),
#[error(transparent)]
ValueName(#[from] crate::parse::section::value_name::Error),
}
}
/// Additional information about a section.
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
pub struct Metadata {
/// The file path of the source, if known.
pub path: Option<PathBuf>,
/// Where the section is coming from.
pub source: crate::Source,
/// The levels of indirection of the file, with 0 being a section
/// that was directly loaded, and 1 being an `include.path` of a
/// level 0 file.
pub level: u8,
/// The trust-level for the section this meta-data is associated with.
pub trust: gix_sec::Trust,
}
/// A section in a git-config file, like `[core]` or `[remote "origin"]`, along with all of its keys.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Section<'a> {
header: crate::parse::section::Header<'a>,
body: section::Body<'a>,
meta: OwnShared<Metadata>,
id: SectionId,
}
/// A function to filter metadata, returning `true` if the corresponding but omitted value can be used.
pub type MetadataFilter = dyn FnMut(&'_ Metadata) -> bool;
/// A strongly typed index into some range.
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Clone, Copy)]
pub(crate) struct Index(pub(crate) usize);
impl Add<Size> for Index {
type Output = Self;
fn add(self, rhs: Size) -> Self::Output {
Self(self.0 + rhs.0)
}
}
/// A strongly typed a size.
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Clone, Copy)]
pub(crate) struct Size(pub(crate) usize);
impl AddAssign<usize> for Size {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs;
}
}
/// The section ID is a monotonically increasing ID used to refer to section bodies.
/// This value does not imply any ordering between sections, as new sections
/// with higher section IDs may be in between lower ID sections after `File` mutation.
///
/// We need to use a section id because `git-config` permits sections with
/// identical names, making it ambiguous when used in maps, for instance.
///
/// This id guaranteed to be unique, but not guaranteed to be compact. In other
/// words, it's possible that a section may have an ID of 3 but the next section
/// has an ID of 5 as 4 was deleted.
#[derive(PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord, Debug)]
pub struct SectionId(pub(crate) usize);
impl Default for SectionId {
fn default() -> Self {
SectionId(usize::MAX)
}
}
/// All section body ids referred to by a section name.
///
/// Note that order in Vec matters as it represents the order
/// of section ids with the matched section and name, and is used for precedence
/// management.
#[derive(PartialEq, Eq, Clone, Debug)]
pub(crate) enum SectionBodyIdsLut<'a> {
/// The list of section ids to use for obtaining the section body.
Terminal(Vec<SectionId>),
/// A hashmap from sub-section names to section ids.
NonTerminal(HashMap<Cow<'a, BStr>, Vec<SectionId>>),
}
#[cfg(test)]
mod tests;
mod write;