Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parsers node add #27

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
811 changes: 809 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ config = { version = "0.14", default-features = false, features = [
"convert-case",
"toml",
] }
serde_yaml = {version = "0.9.33"}
serde = { version = "1" }
serde_json = "1"
dashmap = { version = "6", features = ["serde"] }
Expand Down
3 changes: 3 additions & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ name = "edgelink_core"

[dependencies]
anyhow.workspace = true
jsonschema="0.23.0"
tokio = { workspace = true, features = [
"rt",
"rt-multi-thread",
Expand Down Expand Up @@ -49,8 +50,10 @@ itertools.workspace = true
smallvec.workspace = true
smallstr.workspace = true
inventory.workspace = true
serde_yaml.workspace = true
arrayvec = { workspace = true, features = ["std", "serde"] }


[dev-dependencies]
# Enable test-utilities in dev mode only. This is mostly for tests.
tokio = { workspace = true, features = ["test-util"] }
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/runtime/model/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde_json::Value as JsonValue;

pub mod deser;
pub mod helpers;
pub mod npdeser;

#[derive(serde::Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct RedPortConfig {
Expand Down
177 changes: 177 additions & 0 deletions crates/core/src/runtime/model/json/npdeser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
//! [npdeser] this mod use to de deserializer node logic properties transport to real logic.
//!
//! # example
//! > this appendNewline config is belong to node red core node [file], Used to determine whether
//! > to wrap a file ,it's could It should be a boolean type, but the code logic allows it to be
//! > any non undefined, true false 0 and 1, and any character ,and any str. so need this mod handle
//! > this scene
//! ```js
//! this.appendNewline = n.appendNewline;
//!
//! if ((node.appendNewline) && (!Buffer.isBuffer(data)) && aflg) { data += os.EOL; }
//! ```
//!
#![allow(dead_code)]
use serde::de::{Error, Unexpected, Visitor};
use serde::{de, Deserializer};
use std::str;

pub fn deser_bool_in_if_condition<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
struct BoolVisitor;

impl<'de> de::Visitor<'de> for BoolVisitor {
type Value = bool;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a bool, convert failed")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match str::from_utf8(v) {
Ok(s) => {
if let Some(value) = Self::convert_to_bool(s) {
return value;
}
Ok(true)
}
Err(_) => Err(Error::invalid_value(Unexpected::Bool(false), &self)),
}
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0 {
return Ok(false);
}
Ok(true)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0 {
return Ok(false);
}
Ok(true)
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0 {
return Ok(false);
}
Ok(true)
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0 {
return Ok(false);
}
Ok(true)
}

fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0.0 {
return Ok(false);
}
Ok(true)
}

fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: Error,
{
if v == 0.0 {
return Ok(false);
}
Ok(true)
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
if let Some(value) = Self::convert_to_bool(v) {
return value;
}
Ok(true)
}
}

impl BoolVisitor {
fn convert_to_bool<E>(v: &str) -> Option<Result<<BoolVisitor as Visitor>::Value, E>>
where
E: Error,
{
if v.is_empty() || v == "0" || v.contains("false") || v.contains("False") || v.contains("FALSE") {
return Some(Ok(false));
}
None
}
}

deserializer.deserialize_any(BoolVisitor)
}

#[cfg(test)]
mod tests {
use super::*;
use serde::Deserialize;
use serde_json::json;

#[derive(Deserialize, Debug)]
struct TestNodeConfig {
#[serde(deserialize_with = "crate::runtime::model::json::npdeser::deser_bool_in_if_condition")]
test: bool,
}

#[test]
fn test_deser_bool_in_if_condition() {
let value_str = json!({"test":"xxx"});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(result.test);

let value_str = json!({"test":"true"});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(result.test);

let value_str = json!({"test":"false"});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(!result.test);

let value_str = json!({"test":"False"});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(!result.test);

let value_str = json!({"test":"0"});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(!result.test);

let value_str = json!({"test":1.0});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(result.test);

let value_str = json!({"test":0.0});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(!result.test);

let value_str = json!({"test":0});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(!result.test);

let value_str = json!({"test":1});
let result = TestNodeConfig::deserialize(value_str).unwrap();
assert!(result.test);
}
}
2 changes: 2 additions & 0 deletions crates/core/src/runtime/nodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use crate::*;
pub(crate) mod common_nodes;
mod function_nodes;

mod parsers_nodes;

#[cfg(feature = "net")]
mod network_nodes;

Expand Down
Loading
Loading