From 21e3036ab8a58663dc976bcc17b419dec7836be8 Mon Sep 17 00:00:00 2001 From: YUE Daian Date: Fri, 8 Sep 2023 15:48:46 +0800 Subject: [PATCH] feat: support array type Signed-off-by: YUE Daian --- src/evaluation/value.rs | 157 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 147 insertions(+), 10 deletions(-) diff --git a/src/evaluation/value.rs b/src/evaluation/value.rs index 8da2fd6..7c002c4 100644 --- a/src/evaluation/value.rs +++ b/src/evaluation/value.rs @@ -6,9 +6,103 @@ pub enum Value { Int(i64), Float(f64), String(String), + Array(Vec), Struct(StructValue), } +/// Represent a structure value as defined in the +/// [spec](https://openfeature.dev/specification/types#structure). +#[derive(Clone, Default, PartialEq, Debug)] +pub struct StructValue { + pub fields: HashMap, +} + +impl Value { + pub fn is_bool(&self) -> bool { + match self { + Self::Bool(_) => true, + _ => false, + } + } + + pub fn as_bool(&self) -> Option { + match self { + Self::Bool(value) => Some(*value), + _ => None, + } + } + + pub fn is_i64(&self) -> bool { + match self { + Self::Int(_) => true, + _ => false, + } + } + + pub fn as_i64(&self) -> Option { + match self { + Self::Int(value) => Some(*value), + _ => None, + } + } + + pub fn is_f64(&self) -> bool { + match self { + Self::Float(_) => true, + _ => false, + } + } + + pub fn as_f64(&self) -> Option { + match self { + Self::Float(value) => Some(*value), + _ => None, + } + } + + pub fn is_str(&self) -> bool { + match self { + Self::String(_) => true, + _ => false, + } + } + + pub fn as_str(&self) -> Option<&str> { + match self { + Self::String(value) => Some(&value), + _ => None, + } + } + + pub fn is_array(&self) -> bool { + match self { + Self::Array(_) => true, + _ => false, + } + } + + pub fn as_array(&self) -> Option<&Vec> { + match self { + Self::Array(value) => Some(value), + _ => None, + } + } + + pub fn is_struct(&self) -> bool { + match self { + Self::Struct(_) => true, + _ => false, + } + } + + pub fn as_struct(&self) -> Option<&StructValue> { + match self { + Self::Struct(value) => Some(value), + _ => None, + } + } +} + impl From for Value { fn from(value: bool) -> Self { Self::Bool(value) @@ -81,19 +175,21 @@ impl From<&str> for Value { } } +impl From> for Value +where + T: Into, +{ + fn from(value: Vec) -> Self { + Self::Array(value.into_iter().map(Into::into).collect()) + } +} + impl From for Value { fn from(value: StructValue) -> Self { Self::Struct(value) } } -/// Represent a structure value as defined in the -/// [spec](https://openfeature.dev/specification/types#structure). -#[derive(Clone, Default, PartialEq, Debug)] -pub struct StructValue { - fields: HashMap, -} - impl StructValue { pub fn with_field, V: Into>(mut self, key: S, value: V) -> Self { self.add_field(key, value); @@ -111,14 +207,55 @@ mod tests { #[test] fn build_value() { - let value = StructValue::default() - .with_field("is_male", true) + let alex = StructValue::default() + .with_field("is_male", false) .with_field("id", 100) - .with_field("grade", "97.5") + .with_field("grade", 97.5) .with_field("name", "Alex") + .with_field("friends", vec!["Bob", "Carl"]) .with_field( "other", StructValue::default().with_field("description", "A student"), ); + + let is_male = alex.fields.get("is_male").unwrap(); + assert!(is_male.is_bool()); + assert_eq!(false, is_male.as_bool().unwrap()); + + let id = alex.fields.get("id").unwrap(); + assert!(id.is_i64()); + assert_eq!(100, id.as_i64().unwrap()); + + let grade = alex.fields.get("grade").unwrap(); + assert!(grade.is_f64()); + assert_eq!(97.5, grade.as_f64().unwrap()); + + let name = alex.fields.get("name").unwrap(); + assert!(name.is_str()); + assert_eq!("Alex", alex.fields.get("name").unwrap().as_str().unwrap()); + + let friends = alex.fields.get("friends").unwrap(); + assert!(friends.is_array()); + assert_eq!( + vec![ + Value::String("Bob".to_string()), + Value::String("Carl".to_string()) + ], + *friends.as_array().unwrap() + ); + + let other = alex.fields.get("other").unwrap(); + assert!(other.is_struct()); + assert_eq!( + "A student", + other + .as_struct() + .unwrap() + .fields + .get("description") + .unwrap() + .as_str() + .unwrap() + ); } }