diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 120000
index 0000000..965b606
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1 @@
+../LICENSE-APACHE
\ No newline at end of file
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 120000
index 0000000..76219eb
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1 @@
+../LICENSE-MIT
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ece86f7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,18 @@
+# git-config
+
+**git-config is a library for interacting with `git-config` files.**
+
+#### License
+
+
+Licensed under either of Apache License, Version
+2.0 or MIT license at your option.
+
+
+
+
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in git-config by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+
\ No newline at end of file
diff --git a/src/file.rs b/src/file.rs
index ba3a755..0ac97e0 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -1,23 +1,25 @@
//! This module provides a high level wrapper around a single `git-config` file.
-use crate::parser::{parse_from_bytes, Error, Event, ParsedSectionHeader, Parser};
-use crate::values::{normalize_bytes, normalize_cow, normalize_vec};
-use std::{borrow::Borrow, convert::TryFrom, ops::Deref};
-use std::{borrow::Cow, fmt::Display};
-use std::{
- collections::{HashMap, VecDeque},
- ops::DerefMut,
+use crate::parser::{
+ parse_from_bytes, Error, Event, Key, ParsedSectionHeader, Parser, SectionHeaderName,
};
+use crate::values::{normalize_bytes, normalize_cow, normalize_vec};
+use std::borrow::Borrow;
+use std::borrow::Cow;
+use std::collections::{HashMap, VecDeque};
+use std::convert::TryFrom;
+use std::fmt::Display;
+use std::ops::{Deref, DerefMut};
/// All possible error types that may occur from interacting with [`GitConfig`].
-#[derive(PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord, Debug)]
+#[derive(PartialEq, Eq, Hash, Clone, PartialOrd, Ord, Debug)]
pub enum GitConfigError<'a> {
/// The requested section does not exist.
- SectionDoesNotExist(&'a str),
+ SectionDoesNotExist(SectionHeaderName<'a>),
/// The requested subsection does not exist.
SubSectionDoesNotExist(Option<&'a str>),
/// The key does not exist in the requested section.
- KeyDoesNotExist(&'a str),
+ KeyDoesNotExist(Key<'a>),
/// The conversion into the provided type for methods such as
/// [`GitConfig::get_value`] failed.
FailedConversion,
@@ -68,7 +70,7 @@ enum LookupTreeNode<'a> {
/// time.
pub struct MutableValue<'borrow, 'lookup, 'event> {
section: &'borrow mut Vec>,
- key: &'lookup str,
+ key: Key<'lookup>,
index: usize,
size: usize,
}
@@ -109,7 +111,7 @@ impl MutableValue<'_, '_, '_> {
latest_value
.map(normalize_cow)
.or_else(|| partial_value.map(normalize_vec))
- .ok_or(GitConfigError::KeyDoesNotExist(self.key))
+ .ok_or(GitConfigError::KeyDoesNotExist(self.key.to_owned()))
}
/// Update the value to the provided one. This modifies the value such that
@@ -131,8 +133,10 @@ impl MutableValue<'_, '_, '_> {
self.section
.insert(self.index, Event::Value(Cow::Owned(input)));
self.section.insert(self.index, Event::KeyValueSeparator);
- self.section
- .insert(self.index, Event::Key(Cow::Owned(self.key.into())));
+ self.section.insert(
+ self.index,
+ Event::Key(Key(Cow::Owned(self.key.0.to_string()))),
+ );
}
/// Removes the value. Does nothing when called multiple times in
@@ -193,7 +197,7 @@ impl DerefMut for Offset {
#[derive(Eq, PartialEq, Debug)]
pub struct MutableMultiValue<'borrow, 'lookup, 'event> {
section: &'borrow mut HashMap>>,
- key: &'lookup str,
+ key: Key<'lookup>,
/// Each entry data struct provides sufficient information to index into
/// [`Self::offsets`]. This layer of indirection is used for users to index
/// into the offsets rather than leaking the internal data structures.
@@ -244,7 +248,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
}
if values.is_empty() {
- return Err(GitConfigError::KeyDoesNotExist(self.key));
+ return Err(GitConfigError::KeyDoesNotExist(self.key.to_owned()));
}
Ok(values)
@@ -296,7 +300,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
offset_index,
} = self.indices_and_sizes[index];
MutableMultiValue::set_value_inner(
- self.key,
+ self.key.to_owned(),
&mut self.offsets,
self.section.get_mut(§ion_id).unwrap(),
section_id,
@@ -323,7 +327,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
) in self.indices_and_sizes.iter().zip(input)
{
Self::set_value_inner(
- self.key,
+ self.key.to_owned(),
&mut self.offsets,
self.section.get_mut(section_id).unwrap(),
*section_id,
@@ -350,7 +354,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
} in &self.indices_and_sizes
{
Self::set_value_inner(
- self.key,
+ self.key.to_owned(),
&mut self.offsets,
self.section.get_mut(section_id).unwrap(),
*section_id,
@@ -373,7 +377,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
} in &self.indices_and_sizes
{
Self::set_value_inner(
- self.key,
+ self.key.to_owned(),
&mut self.offsets,
self.section.get_mut(section_id).unwrap(),
*section_id,
@@ -384,7 +388,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
}
fn set_value_inner<'a: 'event>(
- key: &'lookup str,
+ key: Key<'lookup>,
offsets: &mut HashMap>,
section: &mut Vec>,
section_id: SectionId,
@@ -398,7 +402,7 @@ impl<'lookup, 'event> MutableMultiValue<'_, 'lookup, 'event> {
MutableMultiValue::set_offset(offsets, section_id, offset_index, 3);
section.insert(offset, Event::Value(input));
section.insert(offset, Event::KeyValueSeparator);
- section.insert(offset, Event::Key(Cow::Owned(key.into())));
+ section.insert(offset, Event::Key(Key(Cow::Owned(key.0.to_string()))));
}
/// Removes the value at the given index. Does nothing when called multiple
@@ -530,7 +534,7 @@ pub struct GitConfig<'a> {
/// `git-config` file prohibits global values, this vec is limited to only
/// comment, newline, and whitespace events.
frontmatter_events: Vec>,
- section_lookup_tree: HashMap, Vec>>,
+ section_lookup_tree: HashMap, Vec>>,
/// SectionId to section mapping. The value of this HashMap contains actual
/// events.
///
@@ -675,6 +679,7 @@ impl<'event> GitConfig<'event> {
// the "last one wins" resolution strategy by `git-config`).
let section_ids =
self.get_section_ids_by_name_and_subname(section_name, subsection_name)?;
+ let key = Key(key.into());
for section_id in section_ids.iter().rev() {
let mut found_key = false;
@@ -728,6 +733,7 @@ impl<'event> GitConfig<'event> {
) -> Result, GitConfigError<'lookup>> {
let section_ids =
self.get_section_ids_by_name_and_subname(section_name, subsection_name)?;
+ let key = Key(key.into());
for section_id in section_ids.iter().rev() {
let mut size = 0;
@@ -814,7 +820,7 @@ impl<'event> GitConfig<'event> {
subsection_name: Option<&'lookup str>,
key: &'lookup str,
) -> Result>, GitConfigError<'lookup>> {
- let key = key;
+ let key = Key(key.into());
let mut values = vec![];
for section_id in self.get_section_ids_by_name_and_subname(section_name, subsection_name)? {
let mut found_key = false;
@@ -912,6 +918,7 @@ impl<'event> GitConfig<'event> {
let section_ids = self
.get_section_ids_by_name_and_subname(section_name, subsection_name)?
.to_vec();
+ let key = Key(key.into());
let mut offsets = HashMap::new();
let mut entries = vec![];
@@ -1103,26 +1110,23 @@ impl<'event> GitConfig<'event> {
subsection_name: impl Into