From 112af243bfdcf1bca5e0bf4d6154b50efec8aa26 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 29 Sep 2026 19:31:30 -0500 Subject: [PATCH] perf(toml): Reduce parse overhead --- Cargo.toml | 2 +- src/file/format/toml.rs | 50 ++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 874fd180..fd1b5336 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,7 +154,7 @@ toml = ["dep:toml"] serde_core = "1.0.228" async-trait = { version = "0.1.89", optional = true } -toml = { version = "1.0.6", optional = true, default-features = false, features = ["parse", "serde"] } +toml = { version = "1.0.6", optional = true, default-features = false, features = ["parse", "std"] } serde_json = { version = "1.0.149", optional = true } yaml-rust2 = { version = "0.11.0", optional = true } rust-ini = { version = "0.21.3", optional = true } diff --git a/src/file/format/toml.rs b/src/file/format/toml.rs index 454a057c..5b49557f 100644 --- a/src/file/format/toml.rs +++ b/src/file/format/toml.rs @@ -8,42 +8,60 @@ pub(crate) fn parse( text: &str, ) -> Result, Box> { // Parse a TOML value from the provided text - let table = from_toml_table(uri, toml::from_str(text)?); + let table = from_toml_table(uri, toml::de::DeTable::parse(text)?.into_inner())?; Ok(table) } -fn from_toml_table(uri: Option<&String>, table: toml::Table) -> Map { +fn from_toml_table( + uri: Option<&String>, + table: toml::de::DeTable<'_>, +) -> Result, Box> { let mut m = Map::new(); for (key, value) in table { - m.insert(key, from_toml_value(uri, value)); + m.insert( + key.into_inner().into_owned(), + from_toml_value(uri, value.into_inner())?, + ); } - m + Ok(m) } -fn from_toml_value(uri: Option<&String>, value: toml::Value) -> Value { - match value { - toml::Value::String(value) => Value::new(uri, value), - toml::Value::Float(value) => Value::new(uri, value), - toml::Value::Integer(value) => Value::new(uri, value), - toml::Value::Boolean(value) => Value::new(uri, value), +fn from_toml_value( + uri: Option<&String>, + value: toml::de::DeValue<'_>, +) -> Result> { + let value = match value { + toml::de::DeValue::String(value) => Value::new(uri, value.into_owned()), + toml::de::DeValue::Float(value) => { + let float = value.as_str().parse::()?; + if float.is_infinite() && !value.as_str().contains("inf") { + return Err("floating-point number overflowed".into()); + } + Value::new(uri, float) + } + toml::de::DeValue::Integer(value) => { + Value::new(uri, i64::from_str_radix(value.as_str(), value.radix())?) + } + toml::de::DeValue::Boolean(value) => Value::new(uri, value), - toml::Value::Table(table) => { - let m = from_toml_table(uri, table); + toml::de::DeValue::Table(table) => { + let m = from_toml_table(uri, table)?; Value::new(uri, m) } - toml::Value::Array(array) => { + toml::de::DeValue::Array(array) => { let mut l = Vec::new(); for value in array { - l.push(from_toml_value(uri, value)); + l.push(from_toml_value(uri, value.into_inner())?); } Value::new(uri, l) } - toml::Value::Datetime(datetime) => Value::new(uri, datetime.to_string()), - } + toml::de::DeValue::Datetime(datetime) => Value::new(uri, datetime.to_string()), + }; + Ok(value) }