Skip to main content

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