Skip to content

Commit

Permalink
Revert "Merge pull request #146 from Grinkers/rational"
Browse files Browse the repository at this point in the history
This reverts commit 5022df1, reversing
changes made to b48a802.
  • Loading branch information
Grinkers committed Jun 11, 2024
1 parent be0b00a commit 9b540b7
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 66 deletions.
2 changes: 1 addition & 1 deletion examples/to_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn to_vec() {
let v = Edn::List(List::new(vec![
Edn::Key(":my-key".to_string()),
Edn::Int(6),
Edn::Rational((7, 4)),
Edn::Rational("7/4".to_string()),
]));

println!("{:?}", v.to_vec().unwrap());
Expand Down
2 changes: 1 addition & 1 deletion examples/tokenize_edn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn tokenize() {
Edn::Bool(false),
Edn::Key(":f".to_string()),
Edn::Nil,
Edn::Rational((3, 4)),
Edn::Rational("3/4".to_string()),
]));

println!("{edn:?}");
Expand Down
21 changes: 3 additions & 18 deletions src/deserialize/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,23 +187,6 @@ fn read_discard(chars: &mut iter::Enumerate<core::str::Chars<'_>>) -> Result<Opt
}
}

fn num_den_from_slice(slice: impl AsRef<str>) -> Option<(i64, u64)> {
let slice = slice.as_ref();
let index = slice.find('/');

if let Some(i) = index {
let (num, den) = slice.split_at(i); // This can't panic because the index is valid
let num = num.parse::<i64>();
let den = den[1..].parse::<u64>();

if let (Ok(n), Ok(d)) = (num, den) {
return Some((n, d));
}
return None;
}
None
}

fn read_number(n: char, chars: &mut iter::Enumerate<core::str::Chars<'_>>) -> Result<Edn, Error> {
let c_len = chars
.clone()
Expand Down Expand Up @@ -275,7 +258,9 @@ fn read_number(n: char, chars: &mut iter::Enumerate<core::str::Chars<'_>>) -> Re
Ok(Edn::Int(i64::from_str_radix(&n, radix)?))
}
n if n.parse::<f64>().is_ok() => Ok(Edn::Double(n.parse::<f64>()?.into())),
n if num_den_from_slice(&n).is_some() => Ok(Edn::Rational(num_den_from_slice(n).unwrap())),
n if n.contains('/') && n.split('/').all(|d| d.parse::<f64>().is_ok()) => {
Ok(Edn::Rational(n))
}
n if n.to_uppercase().chars().filter(|c| c == &'E').count() > 1 => {
let mut n = n.chars();
read_symbol(n.next().unwrap_or(' '), &mut n.enumerate())
Expand Down
43 changes: 30 additions & 13 deletions src/edn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub enum Edn {
Int(i64),
UInt(u64),
Double(Double),
Rational((i64, u64)),
Rational(String),
Char(char),
Bool(bool),
Nil,
Expand Down Expand Up @@ -254,7 +254,7 @@ impl core::fmt::Display for Edn {
Self::Int(i) => format!("{i}"),
Self::UInt(u) => format!("{u}"),
Self::Double(d) => format!("{d}"),
Self::Rational((n, d)) => format!("{n}/{d}"),
Self::Rational(r) => r.to_string(),
Self::Bool(b) => format!("{b}"),
Self::Char(c) => char_to_edn(*c),
Self::Nil => String::from("nil"),
Expand All @@ -271,7 +271,7 @@ impl Edn {
/// use edn_rs::edn::{Edn, Vector};
///
/// let key = Edn::Key(String::from(":1234"));
/// let q = Edn::Rational((3, 4));
/// let q = Edn::Rational(String::from("3/4"));
/// let i = Edn::Int(12i64);
///
/// assert_eq!(Edn::Vector(Vector::empty()).to_float(), None);
Expand All @@ -287,7 +287,7 @@ impl Edn {
Self::Int(i) => to_double(i).ok(),
Self::UInt(u) => to_double(u).ok(),
Self::Double(d) => Some(d.to_float()),
Self::Rational(r) => Some(rational_to_double(*r)),
Self::Rational(r) => rational_to_double(r),
_ => None,
}
}
Expand All @@ -297,7 +297,7 @@ impl Edn {
/// use edn_rs::edn::{Edn, Vector};
///
/// let key = Edn::Key(String::from(":1234"));
/// let q = Edn::Rational((3, 4));
/// let q = Edn::Rational(String::from("3/4"));
/// let f = Edn::Double(12.3f64.into());
///
/// assert_eq!(Edn::Vector(Vector::empty()).to_float(), None);
Expand All @@ -313,12 +313,12 @@ impl Edn {
Self::Int(i) => Some(*i),
#[allow(clippy::cast_possible_wrap)]
Self::UInt(u) if i64::try_from(*u).is_ok() => Some(*u as i64),
#[cfg(feature = "std")]
#[allow(clippy::cast_possible_truncation)]
Self::Double(d) => Some((*d).to_float().round() as i64),
#[cfg(feature = "std")]
Self::Double(d) => Some((*d).to_float().round() as i64),
#[allow(clippy::cast_possible_truncation)]
Self::Rational(r) => Some(rational_to_double(*r).round() as i64),
#[cfg(feature = "std")]
Self::Rational(r) => Some(rational_to_double(r).unwrap_or(0f64).round() as i64),
_ => None,
}
}
Expand All @@ -339,11 +339,11 @@ impl Edn {
Some((*d).to_float().round() as u64)
}
#[cfg(feature = "std")]
Self::Rational(r) if r.0 > 0 =>
Self::Rational(r) if !r.contains('-') =>
{
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_possible_truncation)]
Some(rational_to_double(*r).round() as u64)
Some(rational_to_double(r)?.round() as u64)
}
_ => None,
}
Expand Down Expand Up @@ -707,9 +707,17 @@ where
format!("{i:?}").parse::<f64>()
}

#[allow(clippy::cast_precision_loss)]
pub(crate) fn rational_to_double((n, d): (i64, u64)) -> f64 {
(n as f64) / (d as f64)
pub(crate) fn rational_to_double(r: &str) -> Option<f64> {
if r.split('/').count() == 2 {
let vals = r
.split('/')
.map(ToString::to_string)
.map(|v| v.parse::<f64>())
.map(Result::ok)
.collect::<Option<Vec<f64>>>()?;
return Some(vals[0] / vals[1]);
}
None
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -775,6 +783,15 @@ mod test {
use alloc::vec;

use super::*;
#[test]
fn parses_rationals() {
assert_eq!(rational_to_double("3/4").unwrap(), 0.75f64);
assert_eq!(rational_to_double("25/5").unwrap(), 5f64);
assert_eq!(rational_to_double("15/4").unwrap(), 3.75f64);
assert_eq!(rational_to_double("3 4"), None);
assert_eq!(rational_to_double("3/4/5"), None);
assert_eq!(rational_to_double("text/moretext"), None);
}

#[test]
fn iterator() {
Expand Down
24 changes: 12 additions & 12 deletions src/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn display_as_json(edn: &Edn) -> String {
}
s
}
Edn::Rational(r) => format!("{}", rational_to_double(*r)),
Edn::Rational(r) => format!("{}", rational_to_double(r).unwrap()),
Edn::Char(c) => format!("'{c}'"),
Edn::Bool(b) => format!("{b}"),
Edn::Nil => String::from("null"),
Expand Down Expand Up @@ -142,11 +142,11 @@ mod test {
#[test]
fn rational_numbers() {
assert_eq!(
display_as_json(&Edn::Rational((3, 4))),
display_as_json(&Edn::Rational("3/4".to_string())),
String::from("0.75")
);
assert_eq!(
display_as_json(&Edn::Rational((-3, 9))),
display_as_json(&Edn::Rational("-3/9".to_string())),
String::from("-0.3333333333333333")
);
}
Expand Down Expand Up @@ -189,7 +189,7 @@ mod test {
Edn::Key(":b".to_string()),
Edn::Str("test".to_string()),
Edn::Char('4'),
Edn::Rational((-3, 4)),
Edn::Rational("-3/4".to_string()),
Edn::Double(4.5f64.into()),
Edn::UInt(4),
]));
Expand All @@ -206,7 +206,7 @@ mod test {
Edn::Key(":b".to_string()),
Edn::Str("test".to_string()),
Edn::Char('4'),
Edn::Rational((-3, 4)),
Edn::Rational("-3/4".to_string()),
Edn::Double(4.5f64.into()),
Edn::UInt(4),
]));
Expand All @@ -223,7 +223,7 @@ mod test {
Edn::Key(":my-bestie".to_string()),
Edn::Str("test".to_string()),
Edn::Char('4'),
Edn::Rational((-3, 4)),
Edn::Rational("-3/4".to_string()),
Edn::Double(4.5f64.into()),
Edn::UInt(4),
]));
Expand All @@ -238,7 +238,7 @@ mod test {
fn simple_map() {
let map = Edn::Map(Map::new(map! {
String::from("1.2") => Edn::Bool(false),
String::from(":belo-monte") => Edn::Rational((3, 4)),
String::from(":belo-monte") => Edn::Rational(String::from("3/4")),
String::from("true") => Edn::Char('d')
}));

Expand All @@ -258,22 +258,22 @@ mod test {
Edn::Bool(false),
Edn::Key(":f".to_string()),
Edn::Nil,
Edn::Rational((3, 4)),
Edn::Rational("3/4".to_string()),
Edn::Set(Set::new(set! {
Edn::Rational((3, 4))
Edn::Rational("3/4".to_string())
})),
])),
Edn::Map(Map::new(map![
String::from("false") => Edn::Key(":f".to_string()),
String::from("nil") => Edn::Rational((3, 4)),
String::from("nil") => Edn::Rational("3/4".to_string()),
String::from(":my-crazy-map") => Edn::Map(Map::new(map![
String::from("false") => Edn::Map(
Map::new( map![
String::from(":f") => Edn::Key(String::from(":b"))
])),
String::from("nil") => Edn::Vector(
Vector::new( vec![
Edn::Rational((3, 4)),
Edn::Rational("3/4".to_string()),
Edn::Int(1i64)
]))
]))
Expand All @@ -293,7 +293,7 @@ mod test {
Edn::Key(":b".to_string()),
Edn::Str("test".to_string()),
Edn::Char('4'),
Edn::Rational((-3, 4)),
Edn::Rational("-3/4".to_string()),
Edn::Double(4.5f64.into()),
Edn::UInt(4),
]))),
Expand Down
11 changes: 6 additions & 5 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/// Edn::Bool(false),
/// Edn::Key(":f".to_string()),
/// Edn::Nil,
/// Edn::Rational((3, 4))
/// Edn::Rational("3/4".to_string())
/// ]
/// )
/// );
Expand All @@ -38,7 +38,7 @@
/// Edn::Bool(false),
/// Edn::Key(":f".to_string()),
/// Edn::Nil,
/// Edn::Rational((3, 4))
/// Edn::Rational("3/4".to_string())
/// }
/// )
/// );
Expand All @@ -50,7 +50,7 @@
/// map!{
/// String::from("1.2") => Edn::Bool(false),
/// // Note `:b` becomes `b`
/// String::from(":b") => Edn::Rational((3, 4))
/// String::from(":b") => Edn::Rational(String::from("3/4"))
/// }
/// )
/// );
Expand Down Expand Up @@ -81,7 +81,7 @@
/// ])),
/// String::from("nil") => Edn::Vector(
/// Vector::new( vec![
/// Edn::Rational((3, 4)),
/// Edn::Rational("3/4".to_string()),
/// Edn::Int(1i64)
/// ]))
/// ]))
Expand Down Expand Up @@ -200,7 +200,8 @@ macro_rules! edn_internal {
};

($num:tt/$den:tt) => {{
Edn::Rational(($num, $den))
let q = std::format!("{:?}/{:?}", $num, $den);
Edn::Rational(q)
}};

(:$key:tt) => {{
Expand Down
5 changes: 4 additions & 1 deletion tests/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ mod test {
Edn::from_str("-43.5143").unwrap(),
Edn::Double(edn::Double::from(-43.5143))
);
assert_eq!(Edn::from_str("43/5143").unwrap(), Edn::Rational((43, 5143)));
assert_eq!(
Edn::from_str("43/5143").unwrap(),
Edn::Rational("43/5143".to_string())
);
assert_eq!(
Edn::from_str("999999999999999999999.0").unwrap(),
Edn::Double(edn::Double::from(1e21f64))
Expand Down
8 changes: 4 additions & 4 deletions tests/emit_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,22 @@ mod tests {
Edn::Bool(false),
Edn::Key(":f".to_string()),
Edn::Nil,
Edn::Rational((3, 4)),
Edn::Rational("3/4".to_string()),
Edn::Set(Set::new(set! {
Edn::Rational((3, 4))
Edn::Rational("3/4".to_string())
})),
])),
Edn::Map(Map::new(map![
String::from("false") => Edn::Key(":f".to_string()),
String::from("nil") => Edn::Rational((3, 4)),
String::from("nil") => Edn::Rational("3/4".to_string()),
String::from(":my-crazy-map") => Edn::Map(Map::new(map![
String::from("false") => Edn::Map(
Map::new( map![
String::from(":f") => Edn::Key(String::from(":b"))
])),
String::from("nil") => Edn::Vector(
Vector::new( vec![
Edn::Rational((3, 4)),
Edn::Rational("3/4".to_string()),
Edn::Int(1i64)
]))
]))
Expand Down
Loading

0 comments on commit 9b540b7

Please sign in to comment.