#![allow(dead_code, unused_imports, unused_variables)]
use std::collections::HashMap;
use super::ast::AstNode;
#[derive(Debug, Clone)]
pub enum Value {
Null,
Boolean(bool),
Integer(i64),
Float(f64),
String(String),
Array(Vec<Value>),
Object(HashMap<String, Value>),
Function {
params: Vec<String>,
body: Vec<AstNode>,
},
StepResult {
name: String,
success: bool,
output: String,
error: Option<String>,
},
}
impl Value {
pub fn as_bool(&self) -> bool {
match self {
Value::Null => false,
Value::Boolean(b) => *b,
Value::Integer(n) => *n != 0,
Value::Float(n) => *n != 0.0,
Value::String(s) => !s.is_empty(),
Value::Array(a) => !a.is_empty(),
Value::Object(o) => !o.is_empty(),
Value::Function { .. } => true,
Value::StepResult { success, .. } => *success,
}
}
pub fn as_string(&self) -> String {
match self {
Value::Null => "null".to_string(),
Value::Boolean(b) => b.to_string(),
Value::Integer(n) => n.to_string(),
Value::Float(n) => n.to_string(),
Value::String(s) => s.clone(),
Value::Array(a) => format!(
"[{}]",
a.iter()
.map(|v| v.as_string())
.collect::<Vec<_>>()
.join(", ")
),
Value::Object(_) => "[object]".to_string(),
Value::Function { .. } => "[function]".to_string(),
Value::StepResult { output, .. } => output.clone(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_value_as_bool() {
assert!(!Value::Null.as_bool());
assert!(Value::Boolean(true).as_bool());
assert!(!Value::Boolean(false).as_bool());
assert!(Value::Integer(1).as_bool());
assert!(!Value::Integer(0).as_bool());
assert!(Value::String("hello".to_string()).as_bool());
assert!(!Value::String(String::new()).as_bool());
}
#[test]
fn test_value_as_string() {
assert_eq!(Value::Integer(42).as_string(), "42");
assert_eq!(Value::Boolean(true).as_string(), "true");
assert_eq!(Value::String("test".to_string()).as_string(), "test");
}
#[test]
fn test_value_as_bool_float() {
assert!(Value::Float(1.0).as_bool());
assert!(!Value::Float(0.0).as_bool());
assert!(Value::Float(-1.5).as_bool());
}
#[test]
fn test_value_as_bool_array() {
assert!(Value::Array(vec![Value::Integer(1)]).as_bool());
assert!(!Value::Array(vec![]).as_bool());
}
#[test]
fn test_value_as_bool_object() {
let mut map = HashMap::new();
map.insert("key".to_string(), Value::Integer(1));
assert!(Value::Object(map).as_bool());
assert!(!Value::Object(HashMap::new()).as_bool());
}
#[test]
fn test_value_as_bool_function() {
assert!(Value::Function {
params: vec![],
body: vec![],
}
.as_bool());
}
#[test]
fn test_value_as_bool_step_result() {
assert!(Value::StepResult {
name: "test".to_string(),
success: true,
output: "ok".to_string(),
error: None,
}
.as_bool());
assert!(!Value::StepResult {
name: "test".to_string(),
success: false,
output: "".to_string(),
error: Some("err".to_string()),
}
.as_bool());
}
#[test]
fn test_value_as_string_float() {
let s = Value::Float(3.15).as_string();
assert!(s.contains("3.15"));
}
#[test]
fn test_value_as_string_null() {
assert_eq!(Value::Null.as_string(), "null");
}
#[test]
fn test_value_as_string_array() {
let arr = Value::Array(vec![Value::Integer(1), Value::Integer(2)]);
let s = arr.as_string();
assert!(s.starts_with('['));
assert!(s.ends_with(']'));
assert!(s.contains("1"));
assert!(s.contains("2"));
}
#[test]
fn test_value_as_string_object() {
assert_eq!(Value::Object(HashMap::new()).as_string(), "[object]");
}
#[test]
fn test_value_as_string_function() {
assert_eq!(
Value::Function {
params: vec![],
body: vec![],
}
.as_string(),
"[function]"
);
}
#[test]
fn test_value_as_string_step_result() {
let sr = Value::StepResult {
name: "build".to_string(),
success: true,
output: "compiled".to_string(),
error: None,
};
assert_eq!(sr.as_string(), "compiled");
}
}