History

feat: `File::section_mut_or_create_new_filter()` to allow chosing which sections to add values to. (#450)

Sebastian Thiel committed 4 years ago

Commit 17455c91 parent 2a839f32 files · +36 −7Browse files

Unified · Split

2 files
  1. git-config/src/file/access/mutate.rs +21 −6
  2. git-config/tests/file/mutable/section.rs +15 −1
git-config/src/file/access/mutate.rs+21−6
@@ -29,19 +29,34 @@ impl<'event> File<'event> { · 28 unmodified lines
2929 .expect("BUG: Section did not have id from lookup")
3030 .to_mut(nl))
3131 }
32−
33− /// Returns an mutable section with a given `name` and optional `subsection_name`, _if it exists_.
32+ /// Returns an mutable section with a given `name` and optional `subsection_name`, _if it exists_, or create a new section.
3433 pub fn section_mut_or_create_new<'a>(
3534 &'a mut self,
3635 name: impl AsRef<str>,
3736 subsection_name: Option<&str>,
37+ ) -> Result<SectionMut<'a, 'event>, section::header::Error> {
38+ self.section_mut_or_create_new_filter(name, subsection_name, &mut |_| true)
39+ }
40+
41+ /// Returns an mutable section with a given `name` and optional `subsection_name`, _if it exists_ **and** passes `filter`, or create
42+ /// a new section.
43+ pub fn section_mut_or_create_new_filter<'a>(
44+ &'a mut self,
45+ name: impl AsRef<str>,
46+ subsection_name: Option<&str>,
47+ filter: &mut MetadataFilter,
3848 ) -> Result<SectionMut<'a, 'event>, section::header::Error> {
3949 let name = name.as_ref();
4050 match self
4151 .section_ids_by_name_and_subname(name.as_ref(), subsection_name)
42− .map(|it| it.rev().next().expect("BUG: Section lookup vec was empty"))
43− {
44− Ok(id) => {
52+ .ok()
53+ .and_then(|it| {
54+ it.rev().find(|id| {
55+ let s = &self.sections[id];
56+ filter(s.meta())
57+ })
58+ }) {
59+ Some(id) => {
4560 let nl = self.detect_newline_style_smallvec();
4661 Ok(self
4762 .sections
@@ -49,7 +64,7 @@ impl<'event> File<'event> { · 1 unmodified line
4964 .expect("BUG: Section did not have id from lookup")
5065 .to_mut(nl))
5166 }
52− Err(_) => self.new_section(name.to_owned(), subsection_name.map(|n| Cow::Owned(n.to_owned()))),
67+ None => self.new_section(name.to_owned(), subsection_name.map(|n| Cow::Owned(n.to_owned()))),
5368 }
5469 }
5570
git-config/tests/file/mutable/section.rs+15−1
@@ -10,7 +10,21 @@ fn section_mut_or_create_new_is_infallible() -> crate::Result { · 9 unmodified lines
1010 let section = config.section_mut_or_create_new("name", Some("subsection"))?;
1111 assert_eq!(section.header().name(), "name");
1212 assert_eq!(section.header().subsection_name().expect("set"), "subsection");
13− assert_eq!(section.to_bstring(), "[name \"subsection\"]\n");
13+ Ok(())
14+}
15+
16+#[test]
17+fn section_mut_or_create_new_filter_may_reject_existing_sections() -> crate::Result {
18+ let mut config = multi_value_section();
19+ let section = config.section_mut_or_create_new_filter("a", None, &mut |_| false)?;
20+ assert_eq!(section.header().name(), "a");
21+ assert_eq!(section.header().subsection_name(), None);
22+ assert_eq!(section.to_bstring(), "[a]\n");
23+ assert_eq!(
24+ section.meta(),
25+ &git_config::file::Metadata::api(),
26+ "new sections are of source 'API'"
27+ );
1428 Ok(())
1529 }
1630