op 'to_float'

main
Ziyang Hu 2 years ago
parent fe7fb4c1ca
commit 15d503b396

@ -5,7 +5,7 @@
* [ ] graph algorithms
* [x] bfs
* [x] dfs
* [ ] shortest path
* [ ] shortest path, SSSP
* [ ] A*
* [ ] Yen's k-shortest
* [ ] all-pairs shortest path

@ -3,6 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use std::mem;
use std::ops::{Div, Rem};
use std::str::FromStr;
use anyhow::{anyhow, bail, ensure, Result};
use itertools::Itertools;
@ -1501,6 +1502,20 @@ fn op_decode_base64(args: &[DataValue]) -> Result<DataValue> {
}
}
define_op!(OP_TO_FLOAT, 1, false, false);
fn op_to_float(args: &[DataValue]) -> Result<DataValue> {
Ok(match &args[0] {
DataValue::Number(n) => n.get_float().into(),
DataValue::String(t) => match t as &str {
"NAN" => f64::NAN.into(),
"INFINITY" => f64::INFINITY.into(),
"NEGATIVE_INFINITY" => f64::NEG_INFINITY.into(),
s => f64::from_str(s)?.into(),
},
v => bail!("'to_float' cannot be applied to {:?}", v),
})
}
pub(crate) fn get_op(name: &str) -> Option<&'static Op> {
Some(match name {
"list" => &OP_LIST,
@ -1595,6 +1610,7 @@ pub(crate) fn get_op(name: &str) -> Option<&'static Op> {
"chunks" => &OP_CHUNKS,
"chunks_exact" => &OP_CHUNKS_EXACT,
"windows" => &OP_WINDOWS,
"to_float" => &OP_TO_FLOAT,
_ => return None,
})
}

@ -63,7 +63,21 @@ impl From<DataValue> for JsonValue {
DataValue::Null => JsonValue::Null,
DataValue::Bool(b) => JsonValue::Bool(b),
DataValue::Number(Number::Int(i)) => JsonValue::Number(i.into()),
DataValue::Number(Number::Float(f)) => json!(f),
DataValue::Number(Number::Float(f)) => {
if f.is_finite() {
json!(f)
} else if f.is_nan() {
json!(())
} else if f.is_infinite() {
if f.is_sign_negative() {
json!("NEGATIVE_INFINITY")
} else {
json!("INFINITY")
}
} else {
unreachable!()
}
}
DataValue::String(t) => JsonValue::String(t.into()),
DataValue::Bytes(bytes) => JsonValue::String(base64::encode(bytes)),
DataValue::List(l) => {
@ -77,10 +91,9 @@ impl From<DataValue> for JsonValue {
}
DataValue::Regex(r) => {
json!(r.0.as_str())
}
// DataValue::Map(m) => {
// JsonValue::Array(m.into_iter().map(|(k, v)| json!([k, v])).collect())
// }
} // DataValue::Map(m) => {
// JsonValue::Array(m.into_iter().map(|(k, v)| json!([k, v])).collect())
// }
}
}
}
@ -215,3 +228,19 @@ impl TryFrom<&'_ JsonValue> for TxId {
Ok(TxId(v))
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
use crate::data::json::JsonValue;
use crate::data::value::DataValue;
#[test]
fn bad_values() {
println!("{}", json!(f64::INFINITY));
println!("{}", JsonValue::from(DataValue::from(f64::INFINITY)));
println!("{}", JsonValue::from(DataValue::from(f64::NEG_INFINITY)));
println!("{}", JsonValue::from(DataValue::from(f64::NAN)));
}
}

Loading…
Cancel
Save