Skip to content

Commit

Permalink
Implement Arbitrary int and floats as strings for full roundtrip pars…
Browse files Browse the repository at this point in the history
…e/emit. No implementation/checks are done.
  • Loading branch information
Grinkers committed Dec 11, 2023
1 parent a33eaa6 commit 3ae348c
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ fn complex_ok() -> Result<(), EdnError> {
- [x] nil `""`
- [x] String `"\"string\""`
- [x] Numbers `"324352"`, `"3442.234"`, `"3/4"`
- [x] Arbitrary Numbers `"4650481213195981094N"`, `"-6.731982E-96M"`. These are stored as strings and not checked for correctness
- [x] Keywords `:a`
- [x] Symbol `sym-bol-s` with a maximum of 200 chars
- [x] Vector `"[1 :2 \"d\"]"`
Expand Down
2 changes: 2 additions & 0 deletions src/deserialize/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ fn read_number(
let mut n = n.chars();
read_symbol(n.next().unwrap_or(' '), &mut n.enumerate())
}
n if n.to_uppercase().ends_with('N') => Ok(Edn::ArbitraryInt(n)),
n if n.to_uppercase().ends_with('M') => Ok(Edn::ArbitraryFloat(n)),
_ => Err(Error::ParseEdn(format!(
"{number} could not be parsed with radix {radix}"
))),
Expand Down
4 changes: 4 additions & 0 deletions src/edn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub enum Edn {
Str(String),
Int(i64),
UInt(u64),
ArbitraryInt(String),
ArbitraryFloat(String),
Double(Double),
Rational(String),
Char(char),
Expand Down Expand Up @@ -249,6 +251,8 @@ impl core::fmt::Display for Edn {
Self::Str(s) => format!("{s:?}"),
Self::Int(i) => format!("{i}"),
Self::UInt(u) => format!("{u}"),
Self::ArbitraryInt(i) => i.to_string(),
Self::ArbitraryFloat(f) => f.to_string(),
Self::Double(d) => format!("{d}"),
Self::Rational(r) => r.to_string(),
Self::Bool(b) => format!("{b}"),
Expand Down
2 changes: 2 additions & 0 deletions src/edn/utils/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ impl<'a> fmt::Display for Type<'a> {
Edn::Nil => formatter.write_str("null"),
Edn::Bool(_) => formatter.write_str("boolean"),
Edn::Int(_) | Edn::UInt(_) => formatter.write_str("integer"),
Edn::ArbitraryInt(_) => formatter.write_str("arbitraryint"),
Edn::ArbitraryFloat(_) => formatter.write_str("arbitraryfloat"),
Edn::Str(_) => formatter.write_str("string"),
Edn::Vector(_) => formatter.write_str("vector"),
#[cfg(feature = "sets")]
Expand Down
2 changes: 2 additions & 0 deletions src/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub fn display_as_json(edn: &Edn) -> String {
Edn::Symbol(s) | Edn::Str(s) => format!("{s:?}"),
Edn::Int(n) => format!("{n}"),
Edn::UInt(n) => format!("{n}"),
Edn::ArbitraryInt(i) => format!("{i:?}"),
Edn::ArbitraryFloat(f) => format!("{f:?}"),
Edn::Double(n) => {
// Rust formats an f64 with a value of 2^5 as "32".
// We do this to ensure all precision is printed if available, but still adds a decimal point for json.
Expand Down
8 changes: 8 additions & 0 deletions tests/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -982,4 +982,12 @@ mod test {
]))
);
}

#[test]
fn arbitrary_numbers() {
assert_eq!(
Edn::from_str("[-6.731982E-96M 4650481213195981094106568258513747645404361846863540722905990782512657236531968143067223662542170794755N]").unwrap(),
Edn::Vector(Vector::new(vec![Edn::ArbitraryFloat("-6.731982E-96M".to_string()), Edn::ArbitraryInt("4650481213195981094106568258513747645404361846863540722905990782512657236531968143067223662542170794755N".to_string())]))
)
}
}

0 comments on commit 3ae348c

Please sign in to comment.