From 798326082f3392a922058b43f7fa5e5daa898fe8 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Fri, 2 Oct 2026 16:29:46 +0200 Subject: [PATCH] feat: add get_section to return a section's keys and values --- src/ini.rs | 24 ++++++++++++++++++++++++ tests/test.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/ini.rs b/src/ini.rs index c6d3115..e538b31 100644 --- a/src/ini.rs +++ b/src/ini.rs @@ -1218,6 +1218,30 @@ impl Ini { &mut self.map } + ///Returns a clone of the `Map` stored in the defined section, with all of its keys and values. + ///Like `get()`, it processes the section name to make case-insensitive access *if* the default constructor is used. + ///## Example + ///```rust + ///use configparser::ini::Ini; + /// + ///let mut config = Ini::new(); + ///config.read(String::from( + /// "[section] + /// key=value + /// valueless")); + ///let section = config.get_section("section").unwrap(); + ///assert_eq!(section.len(), 2); + /////The clone does not borrow `config`, so we can update it while iterating: + ///for key in section.keys() { + /// config.setstr("section", key, Some("updated")); + ///} + ///assert_eq!(config.get("section", "valueless").unwrap(), "updated"); + ///``` + ///Returns `Some(section_map)` if the section exists or else, `None`. + pub fn get_section(&self, section: &str) -> Option>> { + self.map.get(&*self.casefold(section)).cloned() + } + ///Sets an `Option` in the `Map` stored in our struct. If a particular section or key does not exist, it will be automatically created. ///An existing value in the map will be overwritten. You can also set `None` safely. ///## Example diff --git a/tests/test.rs b/tests/test.rs index 221b62a..257d23e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1049,3 +1049,44 @@ fn bool_getters_reject_unknown_values() -> Result<(), Box> { assert!(config.getbool("s", "yes").is_err()); Ok(()) } + +#[test] +fn get_section() -> Result<(), Box> { + let mut config = Ini::new(); + config.load("tests/test.ini")?; + + let topsecret = config.get_section("TopSecret").unwrap(); + assert_eq!( + topsecret.keys().cloned().collect::>(), + HashSet::from([ + String::from("kfc"), + String::from("colon"), + String::from("empty string"), + String::from("none string"), + String::from("password"), + ]) + ); + assert_eq!( + topsecret["kfc"].as_deref(), + Some("the secret herb is orega-") + ); + assert_eq!(topsecret["none string"], None); + assert_eq!(config.get_section("missing"), None); + + for key in config.get_section("values").unwrap().keys() { + config.setstr("values", key, Some("updated")); + } + assert_eq!(config.get("values", "float").unwrap(), "updated"); + assert_eq!(config.get("values", "bool").unwrap(), "updated"); + + let mut config_cs = Ini::new_cs(); + config_cs.load("tests/test.ini")?; + assert_eq!(config_cs.get_section("TopSecret"), None); + assert!( + config_cs + .get_section("topsecret") + .unwrap() + .contains_key("KFC") + ); + Ok(()) +}