Skip to content

Commit

Permalink
Implement Serialize for Value (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkmcc authored Apr 2, 2024
1 parent 2edeba0 commit bfd8906
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 31 deletions.
55 changes: 25 additions & 30 deletions interpreter/src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use crate::{to_value, ExecutionError};
use cel_parser::{ArithmeticOp, Atom, Expression, Member, RelationOp, UnaryOp};
use chrono::{DateTime, Duration, FixedOffset};
use core::ops;
use serde::Serialize;
use serde::{Serialize, Serializer};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::convert::{Infallible, TryFrom, TryInto};
use std::convert::{TryFrom, TryInto};
use std::fmt::{Display, Formatter};
use std::rc::Rc;
use std::sync::Arc;
Expand Down Expand Up @@ -87,6 +87,20 @@ impl From<u64> for Key {
}
}

impl Serialize for Key {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Key::Int(v) => v.serialize(serializer),
Key::Uint(v) => v.serialize(serializer),
Key::Bool(v) => v.serialize(serializer),
Key::String(v) => v.serialize(serializer),
}
}
}

/// Implement conversions from [`Key`] into [`Value`]

impl TryInto<Key> for Value {
Expand Down Expand Up @@ -117,23 +131,18 @@ impl<K: Into<Key>, V: Into<Value>> From<HashMap<K, V>> for Map {
}
}

pub trait TryIntoValue {
type Error: std::error::Error + 'static;
fn try_into_value(self) -> Result<Value, Self::Error>;
}

impl TryIntoValue for Value {
type Error = Infallible;
fn try_into_value(self) -> Result<Value, Self::Error> {
Ok(self)
impl Serialize for &Map {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.map.as_ref().serialize(serializer)
}
}

impl TryIntoValue for Key {
type Error = Infallible;
fn try_into_value(self) -> Result<Value, Self::Error> {
Ok(self.clone().into())
}
pub trait TryIntoValue {
type Error: std::error::Error + 'static;
fn try_into_value(self) -> Result<Value, Self::Error>;
}

impl<T: Serialize> TryIntoValue for T {
Expand All @@ -143,20 +152,6 @@ impl<T: Serialize> TryIntoValue for T {
}
}

impl TryIntoValue for &Value {
type Error = Infallible;
fn try_into_value(self) -> Result<Value, Self::Error> {
Ok(self.clone())
}
}

impl TryIntoValue for &Key {
type Error = Infallible;
fn try_into_value(self) -> Result<Value, Self::Error> {
Ok(self.clone().into())
}
}

#[derive(Debug, Clone)]
pub enum Value {
List(Arc<Vec<Value>>),
Expand Down
26 changes: 25 additions & 1 deletion interpreter/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
// also mentioned in the [serde documentation](https://serde.rs/).

use crate::{objects::Key, Value};
use serde::ser::Error as SerdeError;
use serde::{
ser::{self, Impossible},
Serialize,
Serialize, Serializer as SerdeSerializer,
};
use std::{collections::HashMap, fmt::Display, iter::FromIterator, sync::Arc};
use thiserror::Error;
Expand Down Expand Up @@ -560,14 +561,37 @@ impl ser::Serializer for KeySerializer {
}
}

impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: SerdeSerializer,
{
match *self {
Value::List(ref vec) => vec.as_ref().serialize(serializer),
Value::Map(ref map) => map.serialize(serializer),
Value::Int(i) => serializer.serialize_i64(i),
Value::UInt(u) => serializer.serialize_u64(u),
Value::Float(f) => serializer.serialize_f64(f),
Value::String(ref s) => serializer.serialize_str(s),
Value::Bool(b) => serializer.serialize_bool(b),
Value::Timestamp(ref dt) => serializer.serialize_str(&dt.to_rfc3339()),
Value::Bytes(ref b) => serializer.serialize_bytes(b),
Value::Null => serializer.serialize_unit(),
_ => Err(SerdeError::custom(format!("Unsupported value: {:?}", self))),
}
}
}

/*
* Tests
*/

#[cfg(test)]
mod tests {
use crate::objects::Map;
use crate::{objects::Key, to_value, Value};
use crate::{Context, Program};
use chrono::Duration;
use serde::Serialize;
use serde_bytes::Bytes;
use std::{collections::HashMap, iter::FromIterator, sync::Arc};
Expand Down

0 comments on commit bfd8906

Please sign in to comment.