Skip to content

Commit

Permalink
fix: Value reorg cntd
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Sep 29, 2024
1 parent fb66d9f commit 2a27ef2
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 143 deletions.
2 changes: 1 addition & 1 deletion lykiadb-server/src/engine/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::plan::planner::Planner;
use crate::util::{alloc_shared, Shared};
use crate::value::callable::{Callable, CallableKind, Function, Stateful};
use crate::value::environment::{EnvId, Environment};
use crate::value::{RV, types::eval_binary};
use crate::value::{RV, eval::eval_binary};

use std::sync::Arc;
use std::vec;
Expand Down
139 changes: 2 additions & 137 deletions lykiadb-server/src/value/types.rs → lykiadb-server/src/value/eval.rs
Original file line number Diff line number Diff line change
@@ -1,143 +1,8 @@
use lykiadb_lang::ast::expr::Operation;
use rustc_hash::FxHashMap;
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{Deserialize, Serialize};
use std::ops;
use std::sync::{Arc, RwLock};
use crate::util::alloc_shared;
use std::sync::Arc;
use super::RV;

impl Serialize for RV {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
RV::Str(s) => serializer.serialize_str(s),
RV::Num(n) => serializer.serialize_f64(*n),
RV::Bool(b) => serializer.serialize_bool(*b),
RV::Undefined => serializer.serialize_none(),
RV::NaN => serializer.serialize_none(),
RV::Null => serializer.serialize_none(),
RV::Array(arr) => {
let mut seq = serializer.serialize_seq(None).unwrap();
let arr = (arr as &RwLock<Vec<RV>>).read().unwrap();
for item in arr.iter() {
seq.serialize_element(&item)?;
}
seq.end()
}
RV::Object(obj) => {
let mut map = serializer.serialize_map(None).unwrap();
let arr = (obj as &RwLock<FxHashMap<String, RV>>)
.read()
.unwrap();
for (key, value) in arr.iter() {
map.serialize_entry(key, value)?;
}
map.end()
},
_ => serializer.serialize_none(),
}
}
}

impl<'de> Deserialize<'de> for RV {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = serde_json::Value::deserialize(deserializer)?;
match value {
serde_json::Value::String(s) => Ok(RV::Str(Arc::new(s))),
serde_json::Value::Number(n) => Ok(RV::Num(n.as_f64().unwrap())),
serde_json::Value::Bool(b) => Ok(RV::Bool(b)),
serde_json::Value::Array(arr) => {
let mut vec = Vec::new();
for item in arr {
vec.push(serde_json::from_value(item).unwrap());
}
Ok(RV::Array(alloc_shared(vec)))
}
serde_json::Value::Object(obj) => {
let mut map = FxHashMap::default();
for (key, value) in obj {
map.insert(key, serde_json::from_value(value).unwrap());
}
Ok(RV::Object(alloc_shared(map)))
}
serde_json::Value::Null => Ok(RV::Null),
}
}
}

impl RV {
pub fn as_bool(&self) -> bool {
match &self {
RV::Num(value) => !value.is_nan() && value.abs() > 0.0,
RV::Str(value) => !value.is_empty(),
RV::Bool(value) => *value,
RV::Null | RV::Undefined | RV::NaN => false,
_ => true,
}
}

pub fn as_number(&self) -> Option<f64> {
match self {
RV::Num(value) => Some(*value),
RV::Bool(true) => Some(1.0),
RV::Bool(false) => Some(0.0),
RV::Str(s) => {
if let Ok(num) = s.parse::<f64>() {
Some(num)
} else {
None
}
}
_ => None,
}
}

pub fn eq_any_bool(&self, b: bool) -> bool {
self.as_bool() == b
}

pub fn eq_str_num(&self, n: f64) -> bool {
if let RV::Str(s) = self {
if let Ok(num) = s.parse::<f64>() {
return num == n;
}
}
false
}

pub fn partial_cmp_str_bool(&self, other: bool) -> Option<std::cmp::Ordering> {
if let Some(num) = self.as_number() {
return num.partial_cmp(&if other { 1.0 } else { 0.0 });
}
self.as_bool().partial_cmp(&other)
}

pub fn is_in(&self, other: &RV) -> RV {
match (self, other) {
(RV::Str(lhs), RV::Str(rhs)) => {
RV::Bool(rhs.contains(lhs.as_str()))
}
(lhs, RV::Array(rhs)) => {
RV::Bool(rhs.read().unwrap().contains(&lhs))
}
(RV::Str(key), RV::Object(map)) => {
RV::Bool(map.read().unwrap().contains_key(key.as_str()))
},
_ => RV::Bool(false),
}
}

pub fn not(&self) -> RV {
RV::Bool(!self.as_bool())
}
}

impl PartialEq for RV {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down Expand Up @@ -334,7 +199,7 @@ mod test {

use crate::{
util::alloc_shared,
value::types::{eval_binary, RV},
value::eval::{eval_binary, RV},
};

#[test]
Expand Down
146 changes: 141 additions & 5 deletions lykiadb-server/src/value/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::sync::Arc;

use callable::Callable;
use std::sync::{Arc, RwLock};
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{Deserialize, Serialize};
use rustc_hash::FxHashMap;

use crate::util::alloc_shared;
use crate::util::Shared;
use callable::Callable;

pub mod environment;
pub mod types;
pub mod eval;
pub mod callable;

#[derive(Debug, Clone)]
pub enum RV {
Str(Arc<String>),
Expand All @@ -19,4 +22,137 @@ pub enum RV {
Undefined,
NaN,
Null,
}
}

impl RV {
pub fn as_bool(&self) -> bool {
match &self {
RV::Num(value) => !value.is_nan() && value.abs() > 0.0,
RV::Str(value) => !value.is_empty(),
RV::Bool(value) => *value,
RV::Null | RV::Undefined | RV::NaN => false,
_ => true,
}
}

pub fn as_number(&self) -> Option<f64> {
match self {
RV::Num(value) => Some(*value),
RV::Bool(true) => Some(1.0),
RV::Bool(false) => Some(0.0),
RV::Str(s) => {
if let Ok(num) = s.parse::<f64>() {
Some(num)
} else {
None
}
}
_ => None,
}
}

pub fn eq_any_bool(&self, b: bool) -> bool {
self.as_bool() == b
}

pub fn eq_str_num(&self, n: f64) -> bool {
if let RV::Str(s) = self {
if let Ok(num) = s.parse::<f64>() {
return num == n;
}
}
false
}

pub fn partial_cmp_str_bool(&self, other: bool) -> Option<std::cmp::Ordering> {
if let Some(num) = self.as_number() {
return num.partial_cmp(&if other { 1.0 } else { 0.0 });
}
self.as_bool().partial_cmp(&other)
}

pub fn is_in(&self, other: &RV) -> RV {
match (self, other) {
(RV::Str(lhs), RV::Str(rhs)) => {
RV::Bool(rhs.contains(lhs.as_str()))
}
(lhs, RV::Array(rhs)) => {
RV::Bool(rhs.read().unwrap().contains(&lhs))
}
(RV::Str(key), RV::Object(map)) => {
RV::Bool(map.read().unwrap().contains_key(key.as_str()))
},
_ => RV::Bool(false),
}
}

pub fn not(&self) -> RV {
RV::Bool(!self.as_bool())
}
}


impl Serialize for RV {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
RV::Str(s) => serializer.serialize_str(s),
RV::Num(n) => serializer.serialize_f64(*n),
RV::Bool(b) => serializer.serialize_bool(*b),
RV::Undefined => serializer.serialize_none(),
RV::NaN => serializer.serialize_none(),
RV::Null => serializer.serialize_none(),
RV::Array(arr) => {
let mut seq = serializer.serialize_seq(None).unwrap();
let arr = (arr as &RwLock<Vec<RV>>).read().unwrap();
for item in arr.iter() {
seq.serialize_element(&item)?;
}
seq.end()
}
RV::Object(obj) => {
let mut map = serializer.serialize_map(None).unwrap();
let arr = (obj as &RwLock<FxHashMap<String, RV>>)
.read()
.unwrap();
for (key, value) in arr.iter() {
map.serialize_entry(key, value)?;
}
map.end()
},
_ => serializer.serialize_none(),
}
}
}

impl<'de> Deserialize<'de> for RV {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = serde_json::Value::deserialize(deserializer)?;
match value {
serde_json::Value::String(s) => Ok(RV::Str(Arc::new(s))),
serde_json::Value::Number(n) => Ok(RV::Num(n.as_f64().unwrap())),
serde_json::Value::Bool(b) => Ok(RV::Bool(b)),
serde_json::Value::Array(arr) => {
let mut vec = Vec::new();
for item in arr {
vec.push(serde_json::from_value(item).unwrap());
}
Ok(RV::Array(alloc_shared(vec)))
}
serde_json::Value::Object(obj) => {
let mut map = FxHashMap::default();
for (key, value) in obj {
map.insert(key, serde_json::from_value(value).unwrap());
}
Ok(RV::Object(alloc_shared(map)))
}
serde_json::Value::Null => Ok(RV::Null),
}
}
}

0 comments on commit 2a27ef2

Please sign in to comment.