gix_config/parse/mod.rs
1//! This module handles parsing a `git-config` file. Generally speaking, you
2//! want to use a higher abstraction such as [`File`] unless you have some
3//! explicit reason to work with events instead.
4//!
5//! The workflow for interacting with this is to use
6//! [`from_bytes()`] to obtain all parse events or tokens of the given input.
7//!
8//! On a higher level, one can use [`Events`] to parse all events into a set
9//! of easily interpretable data type, similar to what [`File`] does.
10//!
11//! [`File`]: crate::File
12
13use std::{borrow::Cow, hash::Hash};
14
15use bstr::BStr;
16
17mod nom;
18pub use self::nom::from_bytes;
19mod event;
20#[path = "events.rs"]
21mod events_type;
22pub use events_type::{Events, FrontMatterEvents};
23mod comment;
24mod error;
25///
26pub mod section;
27
28#[cfg(test)]
29pub(crate) mod tests;
30
31/// Syntactic events that occurs in the config. Despite all these variants
32/// holding a [`Cow`] instead over a simple reference, the parser will only emit
33/// borrowed `Cow` variants.
34///
35/// The `Cow` is used here for ease of inserting new, typically owned events as used
36/// in the [`File`] struct when adding values, allowing a mix of owned and borrowed
37/// values.
38///
39/// [`Cow`]: std::borrow::Cow
40/// [`File`]: crate::File
41#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
42pub enum Event<'a> {
43 /// A comment with a comment tag and the comment itself. Note that the
44 /// comment itself may contain additional whitespace and comment markers
45 /// at the beginning, like `# comment` or `; comment`.
46 Comment(Comment<'a>),
47 /// A section header containing the section name and a subsection, if it
48 /// exists. For instance, `remote "origin"` is parsed to `remote` as section
49 /// name and `origin` as subsection name.
50 SectionHeader(section::Header<'a>),
51 /// A name to a value in a section, like `url` in `remote.origin.url`.
52 SectionValueName(section::ValueName<'a>),
53 /// A completed value. This may be any single-line string, including the empty string
54 /// if an implicit boolean value is used.
55 /// Note that these values may contain spaces and any special character. This value is
56 /// also unprocessed, so it may contain double quotes that should be
57 /// [normalized][crate::value::normalize()] before interpretation.
58 Value(Cow<'a, BStr>),
59 /// Represents any token used to signify a newline character. On Unix
60 /// platforms, this is typically just `\n`, but can be any valid newline
61 /// *sequence*. Multiple newlines (such as `\n\n`) will be merged as a single
62 /// newline event containing a string of multiple newline characters.
63 Newline(Cow<'a, BStr>),
64 /// Any value that isn't completed. This occurs when the value is continued
65 /// onto the next line by ending it with a backslash.
66 /// A [`Newline`][Self::Newline] event is guaranteed after, followed by
67 /// either a ValueDone, a Whitespace, or another ValueNotDone.
68 ValueNotDone(Cow<'a, BStr>),
69 /// The last line of a value which was continued onto another line.
70 /// With this it's possible to obtain the complete value by concatenating
71 /// the prior [`ValueNotDone`][Self::ValueNotDone] events.
72 ValueDone(Cow<'a, BStr>),
73 /// A continuous section of insignificant whitespace.
74 ///
75 /// Note that values with internal whitespace will not be separated by this event,
76 /// hence interior whitespace there is always part of the value.
77 Whitespace(Cow<'a, BStr>),
78 /// This event is emitted when the parser counters a valid `=` character
79 /// separating the key and value.
80 /// This event is necessary as it eliminates the ambiguity for whitespace
81 /// events between a key and value event.
82 KeyValueSeparator,
83}
84
85/// A parsed section containing the header and the section events, typically
86/// comprising the keys and their values.
87#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
88pub struct Section<'a> {
89 /// The section name and subsection name, if any.
90 pub header: section::Header<'a>,
91 /// The syntactic events found in this section.
92 pub events: Vec<Event<'a>>,
93}
94
95/// A parsed comment containing the comment marker and comment.
96#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
97pub struct Comment<'a> {
98 /// The comment marker used. This is either a semicolon or octothorpe/hash.
99 pub tag: u8,
100 /// The parsed comment.
101 pub text: Cow<'a, BStr>,
102}
103
104/// A parser error reports the one-indexed line number where the parsing error
105/// occurred, as well as the last parser node and the remaining data to be
106/// parsed.
107#[derive(PartialEq, Debug)]
108pub struct Error {
109 line_number: usize,
110 last_attempted_parser: error::ParseNode,
111 parsed_until: bstr::BString,
112}