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)]
        Key(#[from] crate::parse::section::key::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;