fix: support float value in attributes (#1396)

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Nathan.fooo 2022-10-30 09:35:15 +08:00 committed by GitHub
parent 783fd40f63
commit 9344ea23ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 12 deletions

View File

@ -115,6 +115,10 @@ impl AttributeHashMap {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn to_json(&self) -> Result<String, OTError> {
serde_json::to_string(self).map_err(|err| OTError::serde().context(err))
}
}
impl Display for AttributeHashMap {
@ -210,11 +214,10 @@ impl AttributeValue {
pub fn none() -> Self {
Self { ty: None, value: None }
}
pub fn from_int(val: usize) -> Self {
let value = if val > 0_usize { Some(val.to_string()) } else { None };
pub fn from_int(val: i64) -> Self {
Self {
ty: Some(ValueType::IntType),
value,
value: Some(val.to_string()),
}
}
@ -268,7 +271,7 @@ impl std::convert::From<bool> for AttributeValue {
impl std::convert::From<usize> for AttributeValue {
fn from(value: usize) -> Self {
AttributeValue::from_int(value)
AttributeValue::from_int(value as i64)
}
}
@ -284,6 +287,12 @@ impl std::convert::From<String> for AttributeValue {
}
}
impl std::convert::From<f64> for AttributeValue {
fn from(value: f64) -> Self {
AttributeValue::from_float(value)
}
}
#[derive(Default)]
pub struct AttributeBuilder {
attributes: AttributeHashMap,

View File

@ -70,56 +70,70 @@ impl<'de> Deserialize<'de> for AttributeValue {
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_int(value as usize))
Ok(AttributeValue::from_int(value as i64))
}
fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_float(value as f64))
}
fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(AttributeValue::from_float(value as f64))
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>

View File

@ -1,3 +1,4 @@
mod operation_attribute_test;
mod operation_delete_test;
mod operation_delta_test;
mod operation_insert_test;

View File

@ -0,0 +1,64 @@
use crate::node::script::NodeScript::*;
use crate::node::script::NodeTest;
use lib_ot::core::{AttributeEntry, AttributeValue, Changeset, NodeData};
#[test]
fn operation_update_attribute_with_float_value_test() {
let mut test = NodeTest::new();
let text_node = NodeData::new("text");
let scripts = vec![
InsertNode {
path: 0.into(),
node_data: text_node.clone(),
rev_id: 1,
},
UpdateBody {
path: 0.into(),
changeset: Changeset::Attributes {
new: AttributeEntry::new("value", 12.2).into(),
old: Default::default(),
},
},
AssertNodeAttributes {
path: 0.into(),
expected: r#"{"value":12.2}"#,
},
];
test.run_scripts(scripts);
}
#[test]
fn operation_update_attribute_with_negative_value_test() {
let mut test = NodeTest::new();
let text_node = NodeData::new("text");
let scripts = vec![
InsertNode {
path: 0.into(),
node_data: text_node.clone(),
rev_id: 1,
},
UpdateBody {
path: 0.into(),
changeset: Changeset::Attributes {
new: AttributeEntry::new("value", -12.2).into(),
old: Default::default(),
},
},
AssertNodeAttributes {
path: 0.into(),
expected: r#"{"value":-12.2}"#,
},
UpdateBody {
path: 0.into(),
changeset: Changeset::Attributes {
new: AttributeEntry::new("value", AttributeValue::from_int(-12)).into(),
old: Default::default(),
},
},
AssertNodeAttributes {
path: 0.into(),
expected: r#"{"value":-12}"#,
},
];
test.run_scripts(scripts);
}

View File

@ -47,6 +47,10 @@ pub enum NodeScript {
path: Path,
expected: Option<NodeData>,
},
AssertNodeAttributes {
path: Path,
expected: &'static str,
},
AssertNodeDelta {
path: Path,
expected: DeltaTextOperations,
@ -130,6 +134,10 @@ impl NodeTest {
let node = self.node_tree.get_node_data_at_path(&path);
assert_eq!(node, expected.map(|e| e.into()));
}
NodeScript::AssertNodeAttributes { path, expected } => {
let node = self.node_tree.get_node_data_at_path(&path).unwrap();
assert_eq!(node.attributes.to_json().unwrap(), expected);
}
NodeScript::AssertNumberOfChildrenAtPath { path, expected } => match path {
None => {
let len = self.node_tree.number_of_children(None);