Use BStr instead
This commit is contained in:
parent
f82d32953e
commit
ea0f76d528
7 changed files with 552 additions and 495 deletions
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"Multivar",
|
||||||
|
"autocrlf",
|
||||||
|
"bstr",
|
||||||
|
"gitea",
|
||||||
|
"gpgsign",
|
||||||
|
"implicits",
|
||||||
|
"multivars",
|
||||||
|
"subname"
|
||||||
|
]
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
nom = "6"
|
nom = "6"
|
||||||
|
bstr = "0.2.15"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
318
src/config.rs
318
src/config.rs
|
@ -1,16 +1,16 @@
|
||||||
use crate::parser::{parse_from_str, Event, ParsedSectionHeader, Parser, ParserError};
|
use crate::parser::{parse_from_str, Event, ParsedSectionHeader, Parser, ParserError};
|
||||||
use serde::{ser::SerializeMap, Serialize, Serializer};
|
use bstr::BStr;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::{borrow::Cow, fmt::Display};
|
use std::{borrow::Cow, fmt::Display};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum GitConfigError<'a> {
|
pub enum GitConfigError<'a> {
|
||||||
/// The requested section does not exist.
|
/// The requested section does not exist.
|
||||||
SectionDoesNotExist(&'a str),
|
SectionDoesNotExist(&'a BStr),
|
||||||
/// The requested subsection does not exist.
|
/// The requested subsection does not exist.
|
||||||
SubSectionDoesNotExist(Option<&'a str>),
|
SubSectionDoesNotExist(Option<&'a BStr>),
|
||||||
/// The key does not exist in the requested section.
|
/// The key does not exist in the requested section.
|
||||||
KeyDoesNotExist(&'a str),
|
KeyDoesNotExist(&'a BStr),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// High level `git-config` reader and writer.
|
/// High level `git-config` reader and writer.
|
||||||
|
@ -19,7 +19,7 @@ pub struct GitConfig<'a> {
|
||||||
/// `git-config` file prohibits global values, this vec is limited to only
|
/// `git-config` file prohibits global values, this vec is limited to only
|
||||||
/// comment, newline, and whitespace events.
|
/// comment, newline, and whitespace events.
|
||||||
front_matter_events: Vec<Event<'a>>,
|
front_matter_events: Vec<Event<'a>>,
|
||||||
section_lookup_tree: HashMap<Cow<'a, str>, Vec<LookupTreeNode<'a>>>,
|
section_lookup_tree: HashMap<Cow<'a, BStr>, Vec<LookupTreeNode<'a>>>,
|
||||||
/// SectionId to section mapping. The value of this HashMap contains actual
|
/// SectionId to section mapping. The value of this HashMap contains actual
|
||||||
/// events
|
/// events
|
||||||
sections: HashMap<SectionId, Vec<Event<'a>>>,
|
sections: HashMap<SectionId, Vec<Event<'a>>>,
|
||||||
|
@ -45,7 +45,7 @@ struct SectionId(usize);
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
enum LookupTreeNode<'a> {
|
enum LookupTreeNode<'a> {
|
||||||
Terminal(Vec<SectionId>),
|
Terminal(Vec<SectionId>),
|
||||||
NonTerminal(HashMap<Cow<'a, str>, Vec<SectionId>>),
|
NonTerminal(HashMap<Cow<'a, BStr>, Vec<SectionId>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GitConfig<'a> {
|
impl<'a> GitConfig<'a> {
|
||||||
|
@ -68,8 +68,8 @@ impl<'a> GitConfig<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Current section that we're building
|
// Current section that we're building
|
||||||
let mut current_section_name: Option<Cow<'a, str>> = None;
|
let mut current_section_name: Option<Cow<'a, BStr>> = None;
|
||||||
let mut current_subsection_name: Option<Cow<'a, str>> = None;
|
let mut current_subsection_name: Option<Cow<'a, BStr>> = None;
|
||||||
let mut maybe_section: Option<Vec<Event<'a>>> = None;
|
let mut maybe_section: Option<Vec<Event<'a>>> = None;
|
||||||
|
|
||||||
for event in parser.into_iter() {
|
for event in parser.into_iter() {
|
||||||
|
@ -123,8 +123,8 @@ impl<'a> GitConfig<'a> {
|
||||||
|
|
||||||
fn push_section(
|
fn push_section(
|
||||||
&mut self,
|
&mut self,
|
||||||
current_section_name: Option<Cow<'a, str>>,
|
current_section_name: Option<Cow<'a, BStr>>,
|
||||||
current_subsection_name: Option<Cow<'a, str>>,
|
current_subsection_name: Option<Cow<'a, BStr>>,
|
||||||
maybe_section: &mut Option<Vec<Event<'a>>>,
|
maybe_section: &mut Option<Vec<Event<'a>>>,
|
||||||
) {
|
) {
|
||||||
if let Some(section) = maybe_section.take() {
|
if let Some(section) = maybe_section.take() {
|
||||||
|
@ -203,7 +203,7 @@ impl<'a> GitConfig<'a> {
|
||||||
/// # use serde_git_config::config::GitConfig;
|
/// # use serde_git_config::config::GitConfig;
|
||||||
/// # use std::borrow::Cow;
|
/// # use std::borrow::Cow;
|
||||||
/// # let git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
/// # let git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
||||||
/// assert_eq!(git_config.get_raw_value("core", None, "a"), Ok(&Cow::from("d")));
|
/// assert_eq!(git_config.get_raw_value("core", None, "a"), Ok(&Cow::Borrowed("d".into())));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Consider [`Self::get_raw_multi_value`] if you want to get all values of
|
/// Consider [`Self::get_raw_multi_value`] if you want to get all values of
|
||||||
|
@ -213,16 +213,20 @@ impl<'a> GitConfig<'a> {
|
||||||
///
|
///
|
||||||
/// This function will return an error if the key is not in the requested
|
/// This function will return an error if the key is not in the requested
|
||||||
/// section and subsection, or if the section and subsection do not exist.
|
/// section and subsection, or if the section and subsection do not exist.
|
||||||
pub fn get_raw_value<'b>(
|
pub fn get_raw_value<'b, S: Into<&'b BStr>>(
|
||||||
&self,
|
&self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
) -> Result<&Cow<'a, str>, GitConfigError<'b>> {
|
) -> Result<&Cow<'a, BStr>, GitConfigError<'b>> {
|
||||||
|
let key = key.into();
|
||||||
// Note: cannot wrap around the raw_multi_value method because we need
|
// Note: cannot wrap around the raw_multi_value method because we need
|
||||||
// to guarantee that the highest section id is used (so that we follow
|
// to guarantee that the highest section id is used (so that we follow
|
||||||
// the "last one wins" resolution strategy by `git-config`).
|
// the "last one wins" resolution strategy by `git-config`).
|
||||||
let section_id = self.get_section_id_by_name_and_subname(section_name, subsection_name)?;
|
let section_id = self.get_section_id_by_name_and_subname(
|
||||||
|
section_name.into(),
|
||||||
|
subsection_name.map(Into::into),
|
||||||
|
)?;
|
||||||
|
|
||||||
// section_id is guaranteed to exist in self.sections, else we have a
|
// section_id is guaranteed to exist in self.sections, else we have a
|
||||||
// violated invariant.
|
// violated invariant.
|
||||||
|
@ -273,11 +277,12 @@ impl<'a> GitConfig<'a> {
|
||||||
/// ```
|
/// ```
|
||||||
/// # use serde_git_config::config::{GitConfig, GitConfigError};
|
/// # use serde_git_config::config::{GitConfig, GitConfigError};
|
||||||
/// # use std::borrow::Cow;
|
/// # use std::borrow::Cow;
|
||||||
|
/// # use bstr::BStr;
|
||||||
/// # let mut git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
/// # let mut git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
||||||
/// let mut mut_value = git_config.get_raw_value_mut("core", None, "a")?;
|
/// let mut mut_value = git_config.get_raw_value_mut("core", None, "a")?;
|
||||||
/// assert_eq!(mut_value, &mut Cow::from("d"));
|
/// assert_eq!(mut_value, &mut Cow::<BStr>::Borrowed("d".into()));
|
||||||
/// *mut_value = Cow::Borrowed("hello");
|
/// *mut_value = Cow::Borrowed("hello".into());
|
||||||
/// assert_eq!(git_config.get_raw_value("core", None, "a"), Ok(&Cow::from("hello")));
|
/// assert_eq!(git_config.get_raw_value("core", None, "a"), Ok(&Cow::Borrowed("hello".into())));
|
||||||
/// # Ok::<(), GitConfigError>(())
|
/// # Ok::<(), GitConfigError>(())
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -288,16 +293,20 @@ impl<'a> GitConfig<'a> {
|
||||||
///
|
///
|
||||||
/// This function will return an error if the key is not in the requested
|
/// This function will return an error if the key is not in the requested
|
||||||
/// section and subsection, or if the section and subsection do not exist.
|
/// section and subsection, or if the section and subsection do not exist.
|
||||||
pub fn get_raw_value_mut<'b>(
|
pub fn get_raw_value_mut<'b, S: Into<&'b BStr>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
) -> Result<&mut Cow<'a, str>, GitConfigError<'b>> {
|
) -> Result<&mut Cow<'a, BStr>, GitConfigError<'b>> {
|
||||||
|
let key = key.into();
|
||||||
// Note: cannot wrap around the raw_multi_value method because we need
|
// Note: cannot wrap around the raw_multi_value method because we need
|
||||||
// to guarantee that the highest section id is used (so that we follow
|
// to guarantee that the highest section id is used (so that we follow
|
||||||
// the "last one wins" resolution strategy by `git-config`).
|
// the "last one wins" resolution strategy by `git-config`).
|
||||||
let section_id = self.get_section_id_by_name_and_subname(section_name, subsection_name)?;
|
let section_id = self.get_section_id_by_name_and_subname(
|
||||||
|
section_name.into(),
|
||||||
|
subsection_name.map(Into::into),
|
||||||
|
)?;
|
||||||
|
|
||||||
// section_id is guaranteed to exist in self.sections, else we have a
|
// section_id is guaranteed to exist in self.sections, else we have a
|
||||||
// violated invariant.
|
// violated invariant.
|
||||||
|
@ -320,8 +329,8 @@ impl<'a> GitConfig<'a> {
|
||||||
|
|
||||||
fn get_section_id_by_name_and_subname<'b>(
|
fn get_section_id_by_name_and_subname<'b>(
|
||||||
&'a self,
|
&'a self,
|
||||||
section_name: &'b str,
|
section_name: &'b BStr,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<&'b BStr>,
|
||||||
) -> Result<SectionId, GitConfigError<'b>> {
|
) -> Result<SectionId, GitConfigError<'b>> {
|
||||||
self.get_section_ids_by_name_and_subname(section_name, subsection_name)
|
self.get_section_ids_by_name_and_subname(section_name, subsection_name)
|
||||||
.map(|vec| {
|
.map(|vec| {
|
||||||
|
@ -350,7 +359,7 @@ impl<'a> GitConfig<'a> {
|
||||||
/// # let git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
/// # let git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// git_config.get_raw_multi_value("core", None, "a"),
|
/// git_config.get_raw_multi_value("core", None, "a"),
|
||||||
/// Ok(vec![&Cow::from("b"), &Cow::from("c"), &Cow::from("d")]),
|
/// Ok(vec![&Cow::Borrowed("b".into()), &Cow::Borrowed("c".into()), &Cow::Borrowed("d".into())]),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -362,14 +371,18 @@ impl<'a> GitConfig<'a> {
|
||||||
/// This function will return an error if the key is not in any requested
|
/// This function will return an error if the key is not in any requested
|
||||||
/// section and subsection, or if no instance of the section and subsections
|
/// section and subsection, or if no instance of the section and subsections
|
||||||
/// exist.
|
/// exist.
|
||||||
pub fn get_raw_multi_value<'b>(
|
pub fn get_raw_multi_value<'b, S: Into<&'b BStr>>(
|
||||||
&'a self,
|
&'a self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
) -> Result<Vec<&Cow<'a, str>>, GitConfigError<'b>> {
|
) -> Result<Vec<&Cow<'a, BStr>>, GitConfigError<'b>> {
|
||||||
|
let key = key.into();
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
for section_id in self.get_section_ids_by_name_and_subname(section_name, subsection_name)? {
|
for section_id in self.get_section_ids_by_name_and_subname(
|
||||||
|
section_name.into(),
|
||||||
|
subsection_name.map(Into::into),
|
||||||
|
)? {
|
||||||
let mut found_key = false;
|
let mut found_key = false;
|
||||||
// section_id is guaranteed to exist in self.sections, else we
|
// section_id is guaranteed to exist in self.sections, else we
|
||||||
// have a violated invariant.
|
// have a violated invariant.
|
||||||
|
@ -408,14 +421,26 @@ impl<'a> GitConfig<'a> {
|
||||||
/// ```
|
/// ```
|
||||||
/// # use serde_git_config::config::{GitConfig, GitConfigError};
|
/// # use serde_git_config::config::{GitConfig, GitConfigError};
|
||||||
/// # use std::borrow::Cow;
|
/// # use std::borrow::Cow;
|
||||||
|
/// # use bstr::BStr;
|
||||||
/// # let mut git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
/// # let mut git_config = GitConfig::from_str("[core]a=b\n[core]\na=c\na=d").unwrap();
|
||||||
/// assert_eq!(git_config.get_raw_multi_value("core", None, "a")?, vec!["b", "c", "d"]);
|
/// assert_eq!(
|
||||||
|
/// git_config.get_raw_multi_value("core", None, "a")?,
|
||||||
|
/// vec![
|
||||||
|
/// &Cow::<BStr>::Borrowed("b".into()),
|
||||||
|
/// &Cow::<BStr>::Borrowed("c".into()),
|
||||||
|
/// &Cow::<BStr>::Borrowed("d".into())
|
||||||
|
/// ]
|
||||||
|
/// );
|
||||||
/// for value in git_config.get_raw_multi_value_mut("core", None, "a")? {
|
/// for value in git_config.get_raw_multi_value_mut("core", None, "a")? {
|
||||||
/// *value = Cow::from("g");
|
/// *value = Cow::Borrowed("g".into());
|
||||||
///}
|
///}
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// git_config.get_raw_multi_value("core", None, "a")?,
|
/// git_config.get_raw_multi_value("core", None, "a")?,
|
||||||
/// vec![&Cow::from("g"), &Cow::from("g"), &Cow::from("g")],
|
/// vec![
|
||||||
|
/// &Cow::<BStr>::Borrowed("g".into()),
|
||||||
|
/// &Cow::<BStr>::Borrowed("g".into()),
|
||||||
|
/// &Cow::<BStr>::Borrowed("g".into())
|
||||||
|
/// ],
|
||||||
/// );
|
/// );
|
||||||
/// # Ok::<(), GitConfigError>(())
|
/// # Ok::<(), GitConfigError>(())
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -431,17 +456,21 @@ impl<'a> GitConfig<'a> {
|
||||||
/// This function will return an error if the key is not in any requested
|
/// This function will return an error if the key is not in any requested
|
||||||
/// section and subsection, or if no instance of the section and subsections
|
/// section and subsection, or if no instance of the section and subsections
|
||||||
/// exist.
|
/// exist.
|
||||||
pub fn get_raw_multi_value_mut<'b>(
|
pub fn get_raw_multi_value_mut<'b, S: Into<&'b BStr>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
) -> Result<Vec<&mut Cow<'a, str>>, GitConfigError<'b>> {
|
) -> Result<Vec<&mut Cow<'a, BStr>>, GitConfigError<'b>> {
|
||||||
|
let key = key.into();
|
||||||
let section_ids = self
|
let section_ids = self
|
||||||
.get_section_ids_by_name_and_subname(section_name, subsection_name)?
|
.get_section_ids_by_name_and_subname(
|
||||||
|
section_name.into(),
|
||||||
|
subsection_name.map(Into::into),
|
||||||
|
)?
|
||||||
.to_vec();
|
.to_vec();
|
||||||
let mut found_key = false;
|
let mut found_key = false;
|
||||||
let values: Vec<&mut Cow<'a, str>> = self
|
let values: Vec<&mut Cow<'a, BStr>> = self
|
||||||
.sections
|
.sections
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter_map(|(k, v)| {
|
.filter_map(|(k, v)| {
|
||||||
|
@ -474,8 +503,8 @@ impl<'a> GitConfig<'a> {
|
||||||
|
|
||||||
fn get_section_ids_by_name_and_subname<'b>(
|
fn get_section_ids_by_name_and_subname<'b>(
|
||||||
&'a self,
|
&'a self,
|
||||||
section_name: &'b str,
|
section_name: &'b BStr,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<&'b BStr>,
|
||||||
) -> Result<&[SectionId], GitConfigError<'b>> {
|
) -> Result<&[SectionId], GitConfigError<'b>> {
|
||||||
let section_ids = self
|
let section_ids = self
|
||||||
.section_lookup_tree
|
.section_lookup_tree
|
||||||
|
@ -488,7 +517,7 @@ impl<'a> GitConfig<'a> {
|
||||||
if let Some(subsect_name) = subsection_name {
|
if let Some(subsect_name) = subsection_name {
|
||||||
for node in section_ids {
|
for node in section_ids {
|
||||||
if let LookupTreeNode::NonTerminal(subsection_lookup) = node {
|
if let LookupTreeNode::NonTerminal(subsection_lookup) = node {
|
||||||
maybe_ids = subsection_lookup.get(subsect_name);
|
maybe_ids = subsection_lookup.get(subsect_name.into());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,12 +534,12 @@ impl<'a> GitConfig<'a> {
|
||||||
.ok_or(GitConfigError::SubSectionDoesNotExist(subsection_name))
|
.ok_or(GitConfigError::SubSectionDoesNotExist(subsection_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_raw_value<'b>(
|
pub fn set_raw_value<'b, S: Into<&'b BStr>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
new_value: impl Into<Cow<'a, str>>,
|
new_value: impl Into<Cow<'a, BStr>>,
|
||||||
) -> Result<(), GitConfigError<'b>> {
|
) -> Result<(), GitConfigError<'b>> {
|
||||||
let value = self.get_raw_value_mut(section_name, subsection_name, key)?;
|
let value = self.get_raw_value_mut(section_name, subsection_name, key)?;
|
||||||
*value = new_value.into();
|
*value = new_value.into();
|
||||||
|
@ -530,12 +559,12 @@ impl<'a> GitConfig<'a> {
|
||||||
/// todo: examples and errors
|
/// todo: examples and errors
|
||||||
///
|
///
|
||||||
/// [`get_raw_multi_value_mut`]: Self::get_raw_multi_value_mut
|
/// [`get_raw_multi_value_mut`]: Self::get_raw_multi_value_mut
|
||||||
pub fn set_raw_multi_value<'b>(
|
pub fn set_raw_multi_value<'b, S: Into<&'b BStr>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
section_name: &'b str,
|
section_name: S,
|
||||||
subsection_name: Option<&'b str>,
|
subsection_name: Option<S>,
|
||||||
key: &'b str,
|
key: S,
|
||||||
new_values: Vec<Cow<'a, str>>,
|
new_values: Vec<Cow<'a, BStr>>,
|
||||||
) -> Result<(), GitConfigError<'b>> {
|
) -> Result<(), GitConfigError<'b>> {
|
||||||
let values = self.get_raw_multi_value_mut(section_name, subsection_name, key)?;
|
let values = self.get_raw_multi_value_mut(section_name, subsection_name, key)?;
|
||||||
for (old, new) in values.into_iter().zip(new_values) {
|
for (old, new) in values.into_iter().zip(new_values) {
|
||||||
|
@ -573,6 +602,7 @@ impl Display for GitConfig<'_> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod from_parser {
|
mod from_parser {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test_util::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_empty() {
|
fn parse_empty() {
|
||||||
|
@ -589,14 +619,7 @@ mod from_parser {
|
||||||
let mut config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let mut config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
let expected_separators = {
|
let expected_separators = {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(
|
map.insert(SectionId(0), section_header("core", None));
|
||||||
SectionId(0),
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "core".into(),
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map
|
map
|
||||||
};
|
};
|
||||||
assert_eq!(config.section_headers, expected_separators);
|
assert_eq!(config.section_headers, expected_separators);
|
||||||
|
@ -604,7 +627,7 @@ mod from_parser {
|
||||||
let expected_lookup_tree = {
|
let expected_lookup_tree = {
|
||||||
let mut tree = HashMap::new();
|
let mut tree = HashMap::new();
|
||||||
tree.insert(
|
tree.insert(
|
||||||
Cow::Borrowed("core"),
|
Cow::Borrowed("core".into()),
|
||||||
vec![LookupTreeNode::Terminal(vec![SectionId(0)])],
|
vec![LookupTreeNode::Terminal(vec![SectionId(0)])],
|
||||||
);
|
);
|
||||||
tree
|
tree
|
||||||
|
@ -615,14 +638,14 @@ mod from_parser {
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(0),
|
SectionId(0),
|
||||||
vec![
|
vec![
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("a")),
|
name_event("a"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("b")),
|
value_event("b"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("c")),
|
name_event("c"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("d")),
|
value_event("d"),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
sections
|
sections
|
||||||
|
@ -636,14 +659,7 @@ mod from_parser {
|
||||||
let mut config = GitConfig::from_str("[core.subsec]\na=b\nc=d").unwrap();
|
let mut config = GitConfig::from_str("[core.subsec]\na=b\nc=d").unwrap();
|
||||||
let expected_separators = {
|
let expected_separators = {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(
|
map.insert(SectionId(0), section_header("core", (".", "subsec")));
|
||||||
SectionId(0),
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "core".into(),
|
|
||||||
separator: Some(".".into()),
|
|
||||||
subsection_name: Some("subsec".into()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map
|
map
|
||||||
};
|
};
|
||||||
assert_eq!(config.section_headers, expected_separators);
|
assert_eq!(config.section_headers, expected_separators);
|
||||||
|
@ -651,9 +667,9 @@ mod from_parser {
|
||||||
let expected_lookup_tree = {
|
let expected_lookup_tree = {
|
||||||
let mut tree = HashMap::new();
|
let mut tree = HashMap::new();
|
||||||
let mut inner_tree = HashMap::new();
|
let mut inner_tree = HashMap::new();
|
||||||
inner_tree.insert(Cow::Borrowed("subsec"), vec![SectionId(0)]);
|
inner_tree.insert(Cow::Borrowed("subsec".into()), vec![SectionId(0)]);
|
||||||
tree.insert(
|
tree.insert(
|
||||||
Cow::Borrowed("core"),
|
Cow::Borrowed("core".into()),
|
||||||
vec![LookupTreeNode::NonTerminal(inner_tree)],
|
vec![LookupTreeNode::NonTerminal(inner_tree)],
|
||||||
);
|
);
|
||||||
tree
|
tree
|
||||||
|
@ -664,14 +680,14 @@ mod from_parser {
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(0),
|
SectionId(0),
|
||||||
vec![
|
vec![
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("a")),
|
name_event("a"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("b")),
|
value_event("b"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("c")),
|
name_event("c"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("d")),
|
value_event("d"),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
sections
|
sections
|
||||||
|
@ -685,22 +701,8 @@ mod from_parser {
|
||||||
let mut config = GitConfig::from_str("[core]\na=b\nc=d\n[other]e=f").unwrap();
|
let mut config = GitConfig::from_str("[core]\na=b\nc=d\n[other]e=f").unwrap();
|
||||||
let expected_separators = {
|
let expected_separators = {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(
|
map.insert(SectionId(0), section_header("core", None));
|
||||||
SectionId(0),
|
map.insert(SectionId(1), section_header("other", None));
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "core".into(),
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map.insert(
|
|
||||||
SectionId(1),
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "other".into(),
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map
|
map
|
||||||
};
|
};
|
||||||
assert_eq!(config.section_headers, expected_separators);
|
assert_eq!(config.section_headers, expected_separators);
|
||||||
|
@ -708,11 +710,11 @@ mod from_parser {
|
||||||
let expected_lookup_tree = {
|
let expected_lookup_tree = {
|
||||||
let mut tree = HashMap::new();
|
let mut tree = HashMap::new();
|
||||||
tree.insert(
|
tree.insert(
|
||||||
Cow::Borrowed("core"),
|
Cow::Borrowed("core".into()),
|
||||||
vec![LookupTreeNode::Terminal(vec![SectionId(0)])],
|
vec![LookupTreeNode::Terminal(vec![SectionId(0)])],
|
||||||
);
|
);
|
||||||
tree.insert(
|
tree.insert(
|
||||||
Cow::Borrowed("other"),
|
Cow::Borrowed("other".into()),
|
||||||
vec![LookupTreeNode::Terminal(vec![SectionId(1)])],
|
vec![LookupTreeNode::Terminal(vec![SectionId(1)])],
|
||||||
);
|
);
|
||||||
tree
|
tree
|
||||||
|
@ -723,24 +725,20 @@ mod from_parser {
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(0),
|
SectionId(0),
|
||||||
vec![
|
vec![
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("a")),
|
name_event("a"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("b")),
|
value_event("b"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("c")),
|
name_event("c"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("d")),
|
value_event("d"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(1),
|
SectionId(1),
|
||||||
vec![
|
vec![name_event("e"), Event::KeyValueSeparator, value_event("f")],
|
||||||
Event::Key(Cow::Borrowed("e")),
|
|
||||||
Event::KeyValueSeparator,
|
|
||||||
Event::Value(Cow::Borrowed("f")),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
sections
|
sections
|
||||||
};
|
};
|
||||||
|
@ -756,22 +754,8 @@ mod from_parser {
|
||||||
let mut config = GitConfig::from_str("[core]\na=b\nc=d\n[core]e=f").unwrap();
|
let mut config = GitConfig::from_str("[core]\na=b\nc=d\n[core]e=f").unwrap();
|
||||||
let expected_separators = {
|
let expected_separators = {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert(
|
map.insert(SectionId(0), section_header("core", None));
|
||||||
SectionId(0),
|
map.insert(SectionId(1), section_header("core", None));
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "core".into(),
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map.insert(
|
|
||||||
SectionId(1),
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name: "core".into(),
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
map
|
map
|
||||||
};
|
};
|
||||||
assert_eq!(config.section_headers, expected_separators);
|
assert_eq!(config.section_headers, expected_separators);
|
||||||
|
@ -779,7 +763,7 @@ mod from_parser {
|
||||||
let expected_lookup_tree = {
|
let expected_lookup_tree = {
|
||||||
let mut tree = HashMap::new();
|
let mut tree = HashMap::new();
|
||||||
tree.insert(
|
tree.insert(
|
||||||
Cow::Borrowed("core"),
|
Cow::Borrowed("core".into()),
|
||||||
vec![LookupTreeNode::Terminal(vec![SectionId(0), SectionId(1)])],
|
vec![LookupTreeNode::Terminal(vec![SectionId(0), SectionId(1)])],
|
||||||
);
|
);
|
||||||
tree
|
tree
|
||||||
|
@ -790,24 +774,20 @@ mod from_parser {
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(0),
|
SectionId(0),
|
||||||
vec![
|
vec![
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("a")),
|
name_event("a"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("b")),
|
value_event("b"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
Event::Key(Cow::Borrowed("c")),
|
name_event("c"),
|
||||||
Event::KeyValueSeparator,
|
Event::KeyValueSeparator,
|
||||||
Event::Value(Cow::Borrowed("d")),
|
value_event("d"),
|
||||||
Event::Newline(Cow::Borrowed("\n")),
|
newline_event(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
sections.insert(
|
sections.insert(
|
||||||
SectionId(1),
|
SectionId(1),
|
||||||
vec![
|
vec![name_event("e"), Event::KeyValueSeparator, value_event("f")],
|
||||||
Event::Key(Cow::Borrowed("e")),
|
|
||||||
Event::KeyValueSeparator,
|
|
||||||
Event::Value(Cow::Borrowed("f")),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
sections
|
sections
|
||||||
};
|
};
|
||||||
|
@ -828,11 +808,11 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "a"),
|
config.get_raw_value("core", None, "a"),
|
||||||
Ok(&Cow::Borrowed("b"))
|
Ok(&Cow::Borrowed("b".into()))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "c"),
|
config.get_raw_value("core", None, "c"),
|
||||||
Ok(&Cow::Borrowed("d"))
|
Ok(&Cow::Borrowed("d".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +821,7 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\na=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\na=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "a"),
|
config.get_raw_value("core", None, "a"),
|
||||||
Ok(&Cow::Borrowed("d"))
|
Ok(&Cow::Borrowed("d".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +830,7 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\n[core]\na=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\n[core]\na=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "a"),
|
config.get_raw_value("core", None, "a"),
|
||||||
Ok(&Cow::Borrowed("d"))
|
Ok(&Cow::Borrowed("d".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +839,7 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("foo", None, "a"),
|
config.get_raw_value("foo", None, "a"),
|
||||||
Err(GitConfigError::SectionDoesNotExist("foo"))
|
Err(GitConfigError::SectionDoesNotExist("foo".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +848,7 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", Some("a"), "a"),
|
config.get_raw_value("core", Some("a"), "a"),
|
||||||
Err(GitConfigError::SubSectionDoesNotExist(Some("a")))
|
Err(GitConfigError::SubSectionDoesNotExist(Some("a".into())))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,7 +857,7 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "aaaaaa"),
|
config.get_raw_value("core", None, "aaaaaa"),
|
||||||
Err(GitConfigError::KeyDoesNotExist("aaaaaa"))
|
Err(GitConfigError::KeyDoesNotExist("aaaaaa".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,11 +866,11 @@ mod get_raw_value {
|
||||||
let config = GitConfig::from_str("[core]a=b\n[core.a]a=c").unwrap();
|
let config = GitConfig::from_str("[core]a=b\n[core.a]a=c").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", None, "a"),
|
config.get_raw_value("core", None, "a"),
|
||||||
Ok(&Cow::Borrowed("b"))
|
Ok(&Cow::Borrowed("b".into()))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_value("core", Some("a"), "a"),
|
config.get_raw_value("core", Some("a"), "a"),
|
||||||
Ok(&Cow::Borrowed("c"))
|
Ok(&Cow::Borrowed("c".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -913,7 +893,7 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\na=c").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\na=c").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", None, "a").unwrap(),
|
config.get_raw_multi_value("core", None, "a").unwrap(),
|
||||||
vec!["b", "c"]
|
vec![&Cow::Borrowed("b"), &Cow::Borrowed("c")]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,7 +902,11 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\na=c\n[core]a=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\na=c\n[core]a=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", None, "a").unwrap(),
|
config.get_raw_multi_value("core", None, "a").unwrap(),
|
||||||
vec!["b", "c", "d"]
|
vec![
|
||||||
|
&Cow::Borrowed("b"),
|
||||||
|
&Cow::Borrowed("c"),
|
||||||
|
&Cow::Borrowed("d")
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +915,7 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("foo", None, "a"),
|
config.get_raw_multi_value("foo", None, "a"),
|
||||||
Err(GitConfigError::SectionDoesNotExist("foo"))
|
Err(GitConfigError::SectionDoesNotExist("foo".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +924,7 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", Some("a"), "a"),
|
config.get_raw_multi_value("core", Some("a"), "a"),
|
||||||
Err(GitConfigError::SubSectionDoesNotExist(Some("a")))
|
Err(GitConfigError::SubSectionDoesNotExist(Some("a".into())))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +933,7 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\nc=d").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", None, "aaaaaa"),
|
config.get_raw_multi_value("core", None, "aaaaaa"),
|
||||||
Err(GitConfigError::KeyDoesNotExist("aaaaaa"))
|
Err(GitConfigError::KeyDoesNotExist("aaaaaa".into()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,11 +942,11 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]a=b\n[core.a]a=c").unwrap();
|
let config = GitConfig::from_str("[core]a=b\n[core.a]a=c").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", None, "a").unwrap(),
|
config.get_raw_multi_value("core", None, "a").unwrap(),
|
||||||
vec!["b"]
|
vec![&Cow::Borrowed("b")]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", Some("a"), "a").unwrap(),
|
config.get_raw_multi_value("core", Some("a"), "a").unwrap(),
|
||||||
vec!["c"]
|
vec![&Cow::Borrowed("c")]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,7 +955,11 @@ mod get_raw_multi_value {
|
||||||
let config = GitConfig::from_str("[core]\na=b\na=c\n[core]a=d\n[core]g=g").unwrap();
|
let config = GitConfig::from_str("[core]\na=b\na=c\n[core]a=d\n[core]g=g").unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_raw_multi_value("core", None, "a").unwrap(),
|
config.get_raw_multi_value("core", None, "a").unwrap(),
|
||||||
vec!["b", "c", "d"]
|
vec![
|
||||||
|
&Cow::Borrowed("b"),
|
||||||
|
&Cow::Borrowed("c"),
|
||||||
|
&Cow::Borrowed("d")
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,3 +10,6 @@ pub mod values;
|
||||||
// pub use de::{from_str, Deserializer};
|
// pub use de::{from_str, Deserializer};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
// pub use ser::{to_string, Serializer};
|
// pub use ser::{to_string, Serializer};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod test_util;
|
||||||
|
|
568
src/parser.rs
568
src/parser.rs
File diff suppressed because it is too large
Load diff
73
src/test_util.rs
Normal file
73
src/test_util.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use crate::parser::{Event, ParsedComment, ParsedSectionHeader};
|
||||||
|
|
||||||
|
pub fn section_header_event(
|
||||||
|
name: &str,
|
||||||
|
subsection: impl Into<Option<(&'static str, &'static str)>>,
|
||||||
|
) -> Event<'_> {
|
||||||
|
Event::SectionHeader(section_header(name, subsection))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn section_header(
|
||||||
|
name: &str,
|
||||||
|
subsection: impl Into<Option<(&'static str, &'static str)>>,
|
||||||
|
) -> ParsedSectionHeader<'_> {
|
||||||
|
let name = Cow::Borrowed(name.into());
|
||||||
|
if let Some((separator, subsection_name)) = subsection.into() {
|
||||||
|
ParsedSectionHeader {
|
||||||
|
name,
|
||||||
|
separator: Some(Cow::Borrowed(separator.into())),
|
||||||
|
subsection_name: Some(Cow::Borrowed(subsection_name.into())),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ParsedSectionHeader {
|
||||||
|
name,
|
||||||
|
separator: None,
|
||||||
|
subsection_name: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn name_event(name: &'static str) -> Event<'static> {
|
||||||
|
Event::Key(Cow::Borrowed(name.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn value_event(value: &'static str) -> Event<'static> {
|
||||||
|
Event::Value(Cow::Borrowed(value.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn value_not_done_event(value: &'static str) -> Event<'static> {
|
||||||
|
Event::ValueNotDone(Cow::Borrowed(value.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn value_done_event(value: &'static str) -> Event<'static> {
|
||||||
|
Event::ValueDone(Cow::Borrowed(value.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn newline_event() -> Event<'static> {
|
||||||
|
newline_custom_event("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn newline_custom_event(value: &'static str) -> Event<'static> {
|
||||||
|
Event::Newline(Cow::Borrowed(value.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn whitespace_event(value: &'static str) -> Event<'static> {
|
||||||
|
Event::Whitespace(Cow::Borrowed(value.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn separator_event() -> Event<'static> {
|
||||||
|
Event::KeyValueSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn comment_event(tag: char, msg: &'static str) -> Event<'static> {
|
||||||
|
Event::Comment(comment(tag, msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn comment(comment_tag: char, comment: &'static str) -> ParsedComment<'static> {
|
||||||
|
ParsedComment {
|
||||||
|
comment_tag,
|
||||||
|
comment: Cow::Borrowed(comment.into()),
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,41 +2,51 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
use serde_git_config::parser::{parse_from_str, Event, ParsedSectionHeader};
|
use serde_git_config::parser::{parse_from_str, Event, ParsedSectionHeader};
|
||||||
|
|
||||||
fn gen_section_header(
|
pub fn section_header_event(
|
||||||
name: &str,
|
name: &str,
|
||||||
subsection: impl Into<Option<(&'static str, &'static str)>>,
|
subsection: impl Into<Option<(&'static str, &'static str)>>,
|
||||||
) -> Event<'_> {
|
) -> Event<'_> {
|
||||||
let name = Cow::Borrowed(name);
|
Event::SectionHeader(section_header(name, subsection))
|
||||||
Event::SectionHeader(
|
|
||||||
if let Some((separator, subsection_name)) = subsection.into() {
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name,
|
|
||||||
separator: Some(Cow::Borrowed(separator)),
|
|
||||||
subsection_name: Some(Cow::Borrowed(subsection_name)),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ParsedSectionHeader {
|
|
||||||
name,
|
|
||||||
separator: None,
|
|
||||||
subsection_name: None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn section_header(
|
||||||
|
name: &str,
|
||||||
|
subsection: impl Into<Option<(&'static str, &'static str)>>,
|
||||||
|
) -> ParsedSectionHeader<'_> {
|
||||||
|
let name = Cow::Borrowed(name.into());
|
||||||
|
if let Some((separator, subsection_name)) = subsection.into() {
|
||||||
|
ParsedSectionHeader {
|
||||||
|
name,
|
||||||
|
separator: Some(Cow::Borrowed(separator.into())),
|
||||||
|
subsection_name: Some(Cow::Borrowed(subsection_name.into())),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ParsedSectionHeader {
|
||||||
|
name,
|
||||||
|
separator: None,
|
||||||
|
subsection_name: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn name(name: &'static str) -> Event<'static> {
|
fn name(name: &'static str) -> Event<'static> {
|
||||||
Event::Key(Cow::Borrowed(name))
|
Event::Key(Cow::Borrowed(name.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(value: &'static str) -> Event<'static> {
|
fn value(value: &'static str) -> Event<'static> {
|
||||||
Event::Value(Cow::Borrowed(value))
|
Event::Value(Cow::Borrowed(value.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn newline() -> Event<'static> {
|
fn newline() -> Event<'static> {
|
||||||
Event::Newline(Cow::Borrowed("\n"))
|
newline_custom("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn newline_custom(value: &'static str) -> Event<'static> {
|
||||||
|
Event::Newline(Cow::Borrowed(value.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn whitespace(value: &'static str) -> Event<'static> {
|
fn whitespace(value: &'static str) -> Event<'static> {
|
||||||
Event::Whitespace(Cow::Borrowed(value))
|
Event::Whitespace(Cow::Borrowed(value.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn separator() -> Event<'static> {
|
fn separator() -> Event<'static> {
|
||||||
|
@ -71,7 +81,7 @@ fn personal_config() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_vec(),
|
.into_vec(),
|
||||||
vec![
|
vec![
|
||||||
gen_section_header("user", None),
|
section_header_event("user", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -90,7 +100,7 @@ fn personal_config() {
|
||||||
value("Foo Bar"),
|
value("Foo Bar"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("core", None),
|
section_header_event("core", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -101,7 +111,7 @@ fn personal_config() {
|
||||||
value("input"),
|
value("input"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("push", None),
|
section_header_event("push", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -112,7 +122,7 @@ fn personal_config() {
|
||||||
value("simple"),
|
value("simple"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("commit", None),
|
section_header_event("commit", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -123,7 +133,7 @@ fn personal_config() {
|
||||||
value("true"),
|
value("true"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("gpg", None),
|
section_header_event("gpg", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -134,7 +144,7 @@ fn personal_config() {
|
||||||
value("gpg"),
|
value("gpg"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("url", (" ", "ssh://git@github.com/")),
|
section_header_event("url", (" ", "ssh://git@github.com/")),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -145,7 +155,7 @@ fn personal_config() {
|
||||||
value("\"github://\""),
|
value("\"github://\""),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("url", (" ", "ssh://git@git.eddie.sh/edward/")),
|
section_header_event("url", (" ", "ssh://git@git.eddie.sh/edward/")),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -156,7 +166,7 @@ fn personal_config() {
|
||||||
value("\"gitea://\""),
|
value("\"gitea://\""),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("pull", None),
|
section_header_event("pull", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -167,7 +177,7 @@ fn personal_config() {
|
||||||
value("only"),
|
value("only"),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
gen_section_header("init", None),
|
section_header_event("init", None),
|
||||||
newline(),
|
newline(),
|
||||||
|
|
||||||
whitespace(" "),
|
whitespace(" "),
|
||||||
|
@ -203,6 +213,6 @@ fn parse_whitespace() {
|
||||||
fn newline_events_are_merged() {
|
fn newline_events_are_merged() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_from_str("\n\n\n\n\n").unwrap().into_vec(),
|
parse_from_str("\n\n\n\n\n").unwrap().into_vec(),
|
||||||
vec![Event::Newline("\n\n\n\n\n".into())]
|
vec![newline_custom("\n\n\n\n\n")]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue