Skip to content

Commit d0799d3

Browse files
committed
feat: SectionMut::push_with_comment(key, comment) to add a new variable with a comment.
This is useful for providing more information about a value at hand, especially if it was added programmatically and then shows up in the configuration.
1 parent 722290d commit d0799d3

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

git-config/src/file/mutable/section.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,26 @@ pub struct SectionMut<'a, 'event> {
2828

2929
/// Mutating methods.
3030
impl<'a, 'event> SectionMut<'a, 'event> {
31-
/// Adds an entry to the end of this section name `key` and `value`. If `value` is None`, no equal sign will be written leaving
31+
/// Adds an entry to the end of this section name `key` and `value`. If `value` is `None`, no equal sign will be written leaving
3232
/// just the key. This is useful for boolean values which are true if merely the key exists.
3333
pub fn push<'b>(&mut self, key: Key<'event>, value: Option<&'b BStr>) {
34+
self.push_with_comment_inner(key, value, None)
35+
}
36+
37+
/// Adds an entry to the end of this section name `key` and `value`. If `value` is `None`, no equal sign will be written leaving
38+
/// just the key. This is useful for boolean values which are true if merely the key exists.
39+
/// `comment` has to be the text to put right after the value and behind a `#` character. Note that newlines are silently transformed
40+
/// into spaces.
41+
pub fn push_with_comment<'b, 'c>(
42+
&mut self,
43+
key: Key<'event>,
44+
value: Option<&'b BStr>,
45+
comment: impl Into<&'c BStr>,
46+
) {
47+
self.push_with_comment_inner(key, value, comment.into().into())
48+
}
49+
50+
fn push_with_comment_inner(&mut self, key: Key<'event>, value: Option<&BStr>, comment: Option<&BStr>) {
3451
let body = &mut self.section.body.0;
3552
if let Some(ws) = &self.whitespace.pre_key {
3653
body.push(Event::Whitespace(ws.clone()));
@@ -44,6 +61,21 @@ impl<'a, 'event> SectionMut<'a, 'event> {
4461
}
4562
None => body.push(Event::Value(Cow::Borrowed("".into()))),
4663
}
64+
if let Some(comment) = comment {
65+
body.push(Event::Whitespace(Cow::Borrowed(" ".into())));
66+
body.push(Event::Comment(parse::Comment {
67+
tag: b'#',
68+
text: Cow::Owned({
69+
let mut c = Vec::with_capacity(comment.len());
70+
let mut bytes = comment.iter().peekable();
71+
if !bytes.peek().map_or(true, |b| b.is_ascii_whitespace()) {
72+
c.insert(0, b' ');
73+
}
74+
c.extend(bytes.map(|b| (*b == b'\n').then(|| b' ').unwrap_or(*b)));
75+
c.into()
76+
}),
77+
}));
78+
}
4779
if self.implicit_newline {
4880
body.push(Event::Newline(BString::from(self.newline.to_vec()).into()));
4981
}

git-config/tests/file/mutable/section.rs

+31
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,37 @@ mod push {
202202
}
203203
}
204204

205+
mod push_with_comment {
206+
use git_config::parse::section::Key;
207+
208+
#[test]
209+
fn various_comments_and_escaping() {
210+
for (comment, expected) in [
211+
("", "$head\tk = v #$nl"),
212+
("this is v!", "$head\tk = v # this is v!$nl"),
213+
(" no double space", "$head\tk = v # no double space$nl"),
214+
("\tno double whitespace", "$head\tk = v #\tno double whitespace$nl"),
215+
(
216+
"one\ntwo\nnewlines are replaced with space",
217+
"$head\tk = v # one two newlines are replaced with space$nl",
218+
),
219+
(
220+
"a\rb\r\nlinefeeds aren't special",
221+
"$head\tk = v # a\rb\r linefeeds aren't special$nl",
222+
),
223+
] {
224+
let mut config = git_config::File::default();
225+
let mut section = config.new_section("a", None).unwrap();
226+
section.set_implicit_newline(false);
227+
section.push_with_comment(Key::try_from("k").unwrap(), Some("v".into()), comment);
228+
let expected = expected
229+
.replace("$head", &format!("[a]{nl}", nl = section.newline()))
230+
.replace("$nl", &section.newline().to_string());
231+
assert_eq!(config.to_bstring(), expected);
232+
}
233+
}
234+
}
235+
205236
mod set_leading_whitespace {
206237
use std::{borrow::Cow, convert::TryFrom};
207238

0 commit comments

Comments
 (0)