From 659d890ecf0303c40b3709317dcf6a47c4daa3a5 Mon Sep 17 00:00:00 2001 From: NitinL <37251096+initinll@users.noreply.github.com> Date: Thu, 9 Feb 2023 17:17:45 +0530 Subject: [PATCH] Added fix for #7981 - Replaced crate serde_ini with rust-ini for package nu-command/from (#8009) # Description Added fix for #7981 - Replaced crate serde_ini with rust-ini for package nu-command/from # Tests + Formatting Added a test to support addition of the rust-ini crate. `cargo test --package nu-command --lib -- formats::from::ini::tests --nocapture` Executed all tests. `cargo test --workspace` --------- Co-authored-by: Nitin Londhe --- Cargo.lock | 45 ++++++++----- crates/nu-command/Cargo.toml | 2 +- crates/nu-command/src/formats/from/ini.rs | 82 ++++++++++++++++++----- crates/nu-command/src/formats/from/mod.rs | 2 +- 4 files changed, 95 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3a3cbd91f..510edf9aec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1078,6 +1078,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + [[package]] name = "doc-comment" version = "0.3.3" @@ -2786,9 +2792,9 @@ dependencies = [ "rstest", "rusqlite", "rust-embed", + "rust-ini", "same-file", "serde", - "serde_ini", "serde_urlencoded", "serde_yaml", "sha2", @@ -3300,6 +3306,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown 0.12.3", +] + [[package]] name = "os_str_bytes" version = "6.4.1" @@ -4249,12 +4265,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "result" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560" - [[package]] name = "riscv" version = "0.7.0" @@ -4378,6 +4388,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if 1.0.0", + "ordered-multimap", +] + [[package]] name = "rust_decimal" version = "1.26.1" @@ -4580,17 +4600,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_ini" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" -dependencies = [ - "result", - "serde", - "void", -] - [[package]] name = "serde_json" version = "1.0.85" diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 1ab0c9b1a8..ddeb5fba20 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -76,7 +76,7 @@ roxmltree = "0.17.0" rust-embed = "6.3.0" same-file = "1.0.6" serde = { version = "1.0.123", features = ["derive"] } -serde_ini = "0.2.0" +rust-ini = "0.18.0" serde_urlencoded = "0.7.0" serde_yaml = "0.9.4" sha2 = "0.10.0" diff --git a/crates/nu-command/src/formats/from/ini.rs b/crates/nu-command/src/formats/from/ini.rs index 4875e2b6ed..f5ac7482ee 100644 --- a/crates/nu-command/src/formats/from/ini.rs +++ b/crates/nu-command/src/formats/from/ini.rs @@ -1,4 +1,3 @@ -use indexmap::map::IndexMap; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -58,23 +57,50 @@ pub fn from_ini_string_to_value( span: Span, val_span: Span, ) -> Result { - let v: Result>, serde_ini::de::Error> = - serde_ini::from_str(&s); - match v { - Ok(index_map) => { - let (cols, vals) = index_map - .into_iter() - .fold((vec![], vec![]), |mut acc, (k, v)| { - let (cols, vals) = v.into_iter().fold((vec![], vec![]), |mut acc, (k, v)| { - acc.0.push(k); - acc.1.push(Value::String { val: v, span }); - acc + let ini_config: Result = ini::Ini::load_from_str(&s); + + match ini_config { + Ok(config) => { + let mut sections: Vec = Vec::new(); + let mut sections_key_value_pairs: Vec = Vec::new(); + + for (section, properties) in config.iter() { + let mut keys_for_section: Vec = Vec::new(); + let mut values_for_section: Vec = Vec::new(); + + // section + match section { + Some(section_name) => { + sections.push(section_name.to_owned()); + } + None => { + sections.push(String::new()); + } + } + + // section's key value pairs + for (key, value) in properties.iter() { + keys_for_section.push(key.to_owned()); + values_for_section.push(Value::String { + val: value.to_owned(), + span, }); - acc.0.push(k); - acc.1.push(Value::Record { cols, vals, span }); - acc + } + + // section with its key value pairs + sections_key_value_pairs.push(Value::Record { + cols: keys_for_section, + vals: values_for_section, + span, }); - Ok(Value::Record { cols, vals, span }) + } + + // all sections with all its key value pairs + Ok(Value::Record { + cols: sections, + vals: sections_key_value_pairs, + span, + }) } Err(err) => Err(ShellError::UnsupportedInput( format!("Could not load ini: {err}"), @@ -104,4 +130,28 @@ mod tests { test_examples(FromIni {}) } + + #[test] + fn read_ini_config_passes() { + let ini_test_config = r" + min-width=450 + max-width=820 + + [normal] + sound-file=/usr/share/sounds/freedesktop/stereo/dialog-information.oga + + [critical] + border-color=FAB387ff + default-timeout=20 + sound-file=/usr/share/sounds/freedesktop/stereo/dialog-warning.oga + "; + + let result = from_ini_string_to_value( + ini_test_config.to_owned(), + Span::test_data(), + Span::test_data(), + ); + + assert!(result.is_ok()); + } } diff --git a/crates/nu-command/src/formats/from/mod.rs b/crates/nu-command/src/formats/from/mod.rs index defb180daf..f1e3c2c67e 100644 --- a/crates/nu-command/src/formats/from/mod.rs +++ b/crates/nu-command/src/formats/from/mod.rs @@ -19,10 +19,10 @@ mod yaml; pub use self::csv::FromCsv; pub use self::toml::FromToml; pub use self::url::FromUrl; +pub use crate::formats::from::ini::FromIni; pub use command::From; pub use eml::FromEml; pub use ics::FromIcs; -pub use ini::FromIni; pub use json::FromJson; pub use nuon::FromNuon; pub use ods::FromOds;