From 059595585079ed4b9f9f47042b7b2238ecb29151 Mon Sep 17 00:00:00 2001 From: Ryan Goodfellow Date: Fri, 29 Nov 2024 18:50:14 -0800 Subject: [PATCH] feat(value,entry): i128 for integers, autoformat safe KdlEntryFormat (#91) --- src/entry.rs | 15 ++++++++++++++- src/v2_parser.rs | 15 ++++++++------- src/value.rs | 14 +++++++------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/entry.rs b/src/entry.rs index ff15095..f941c83 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -163,7 +163,17 @@ impl KdlEntry { /// Auto-formats this entry. pub fn autoformat(&mut self) { - self.format = None; + // TODO once MSRV allows: + //self.format.take_if(|f| !f.autoformat_keep); + if !self + .format + .as_ref() + .map(|f| f.autoformat_keep) + .unwrap_or(false) + { + self.format = None + } + if let Some(name) = &mut self.name { name.autoformat(); } @@ -265,6 +275,8 @@ pub struct KdlEntryFormat { pub after_key: String, /// Whitespace and comments between an entry's equals sign and its value. pub after_eq: String, + /// Do not clobber this format during autoformat + pub autoformat_keep: bool, } #[cfg(test)] @@ -378,6 +390,7 @@ mod test { after_ty: "".into(), after_key: "".into(), after_eq: "".into(), + autoformat_keep: false }), ty: Some("\"m\\\"eh\"".parse()?), value: KdlValue::Integer(0xdeadbeef), diff --git a/src/v2_parser.rs b/src/v2_parser.rs index c8541f0..f9697bd 100644 --- a/src/v2_parser.rs +++ b/src/v2_parser.rs @@ -1295,7 +1295,7 @@ fn integer_test() { } /// `integer := digit (digit | '_')*` -fn integer_base(input: &mut Input<'_>) -> PResult { +fn integer_base(input: &mut Input<'_>) -> PResult { ( digit1, cut_err(repeat( @@ -1321,7 +1321,7 @@ fn hex(input: &mut Input<'_>) -> PResult { ), )) .try_map(|(l, r): (&str, Vec<&str>)| { - i64::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 16) + i128::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 16) .map(|x| x * mult) .map(KdlValue::Integer) }) @@ -1345,8 +1345,9 @@ fn test_hex() { KdlValue::Integer(0xdeadbeef123) ); assert!( - hex.parse(new_input("0xABCDEF0123456789abcdef")).is_err(), - "i64 overflow" + hex.parse(new_input("0xABCDEF0123456789abcdef0123456789")) + .is_err(), + "i128 overflow" ); assert!(hex.parse(new_input("0x_deadbeef123")).is_err()); @@ -1365,7 +1366,7 @@ fn octal(input: &mut Input<'_>) -> PResult { ), )) .try_map(|(l, r): (&str, Vec<&str>)| { - i64::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 8) + i128::from_str_radix(&format!("{l}{}", str::replace(&r.join(""), "_", "")), 8) .map(|x| x * mult) .map(KdlValue::Integer) }) @@ -1395,7 +1396,7 @@ fn binary(input: &mut Input<'_>) -> PResult { cut_err( (alt(("0", "1")), repeat(0.., alt(("0", "1", "_")))).try_map( move |(x, xs): (&str, Vec<&str>)| { - i64::from_str_radix(&format!("{x}{}", str::replace(&xs.join(""), "_", "")), 2) + i128::from_str_radix(&format!("{x}{}", str::replace(&xs.join(""), "_", "")), 2) .map(|x| x * mult) .map(KdlValue::Integer) }, @@ -1426,7 +1427,7 @@ fn test_binary() { assert!(binary.parse(new_input("123")).is_err()); } -fn sign(input: &mut Input<'_>) -> PResult { +fn sign(input: &mut Input<'_>) -> PResult { let sign = opt(alt(('+', '-'))).parse_next(input)?; let mult = if let Some(sign) = sign { if sign == '+' { diff --git a/src/value.rs b/src/value.rs index 33962e6..733a3ed 100644 --- a/src/value.rs +++ b/src/value.rs @@ -8,7 +8,7 @@ pub enum KdlValue { /// A non-float [KDL /// Number](https://github.com/kdl-org/kdl/blob/main/SPEC.md#number) - Integer(i64), + Integer(i128), /// A floating point [KDL /// Number](https://github.com/kdl-org/kdl/blob/main/SPEC.md#number) @@ -76,8 +76,8 @@ impl std::hash::Hash for KdlValue { *val }; // Good enough to be close-ish for our purposes. - (val.trunc() as i64).hash(state); - (val.fract() as i64).hash(state); + (val.trunc() as i128).hash(state); + (val.fract() as i128).hash(state); } KdlValue::Bool(val) => val.hash(state), KdlValue::Null => core::mem::discriminant(self).hash(state), @@ -121,9 +121,9 @@ impl KdlValue { } } - /// Returns `Some(i64)` if the `KdlValue` is a [`KdlValue::Integer`], + /// Returns `Some(i128)` if the `KdlValue` is a [`KdlValue::Integer`], /// otherwise returns `None`. - pub fn as_integer(&self) -> Option { + pub fn as_integer(&self) -> Option { use KdlValue::*; match self { Integer(i) => Some(*i), @@ -219,8 +219,8 @@ impl KdlValue { } } -impl From for KdlValue { - fn from(value: i64) -> Self { +impl From for KdlValue { + fn from(value: i128) -> Self { KdlValue::Integer(value) } }