glyph_types/
value.rs

1//! Runtime value representation for Glyph
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fmt;
6
7/// Runtime values in Glyph
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub enum Value {
10    /// Integer value
11    Int(i64),
12
13    /// Floating point value
14    Float(f64),
15
16    /// String value
17    Str(String),
18
19    /// Boolean value
20    Bool(bool),
21
22    /// Byte array
23    Bytes(Vec<u8>),
24
25    /// None/unit value
26    None,
27
28    /// List of values
29    List(Vec<Value>),
30
31    /// Dictionary of string keys to values
32    Dict(HashMap<String, Value>),
33
34    /// Optional value
35    Optional(Option<Box<Value>>),
36
37    /// Promise (async computation)
38    Promise(PromiseState),
39
40    /// Result type
41    Result(Result<Box<Value>, Box<Value>>),
42
43    /// Function (not directly serializable)
44    #[serde(skip)]
45    Function {
46        params: Vec<String>,
47        body: Vec<u8>, // Bytecode or AST reference
48    },
49}
50
51/// State of a promise
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub enum PromiseState {
54    Pending,
55    Resolved(Box<Value>),
56    Rejected(String),
57}
58
59impl Value {
60    /// Get the type of this value
61    pub fn get_type(&self) -> crate::Type {
62        use crate::Type;
63
64        match self {
65            Value::Int(_) => Type::Int,
66            Value::Float(_) => Type::Float,
67            Value::Str(_) => Type::Str,
68            Value::Bool(_) => Type::Bool,
69            Value::Bytes(_) => Type::Bytes,
70            Value::None => Type::Unit,
71            Value::List(items) => {
72                // Infer list type from first element or use Unknown
73                let inner = items.first().map(|v| v.get_type()).unwrap_or(Type::Unknown);
74                Type::List(Box::new(inner))
75            }
76            Value::Dict(map) => {
77                // All keys are strings, infer value type
78                let value_type = map
79                    .values()
80                    .next()
81                    .map(|v| v.get_type())
82                    .unwrap_or(Type::Unknown);
83                Type::Dict(Box::new(Type::Str), Box::new(value_type))
84            }
85            Value::Optional(opt) => {
86                let inner = opt.as_ref().map(|v| v.get_type()).unwrap_or(Type::Unknown);
87                Type::Optional(Box::new(inner))
88            }
89            Value::Promise(_) => Type::Promise(Box::new(Type::Unknown)),
90            Value::Result(res) => match res {
91                Ok(v) => Type::Result(Box::new(v.get_type()), Box::new(Type::Unknown)),
92                Err(e) => Type::Result(Box::new(Type::Unknown), Box::new(e.get_type())),
93            },
94            Value::Function { params, .. } => Type::Function {
95                params: params
96                    .iter()
97                    .map(|name| (name.clone(), Type::Unknown))
98                    .collect(),
99                return_type: Box::new(Type::Unknown),
100            },
101        }
102    }
103
104    /// Check if this value is truthy
105    pub fn is_truthy(&self) -> bool {
106        match self {
107            Value::Bool(b) => *b,
108            Value::None => false,
109            Value::Int(i) => *i != 0,
110            Value::Float(f) => *f != 0.0,
111            Value::Str(s) => !s.is_empty(),
112            Value::List(l) => !l.is_empty(),
113            Value::Dict(d) => !d.is_empty(),
114            Value::Bytes(b) => !b.is_empty(),
115            Value::Optional(opt) => opt.is_some(),
116            _ => true,
117        }
118    }
119}
120
121impl fmt::Display for Value {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        match self {
124            Value::Int(i) => write!(f, "{i}"),
125            Value::Float(fl) => write!(f, "{fl}"),
126            Value::Str(s) => write!(f, "\"{s}\""),
127            Value::Bool(b) => write!(f, "{b}"),
128            Value::Bytes(b) => write!(f, "bytes({})", b.len()),
129            Value::None => write!(f, "None"),
130            Value::List(items) => {
131                write!(f, "[")?;
132                for (i, item) in items.iter().enumerate() {
133                    if i > 0 {
134                        write!(f, ", ")?;
135                    }
136                    write!(f, "{item}")?;
137                }
138                write!(f, "]")
139            }
140            Value::Dict(map) => {
141                write!(f, "{{")?;
142                for (i, (k, v)) in map.iter().enumerate() {
143                    if i > 0 {
144                        write!(f, ", ")?;
145                    }
146                    write!(f, "\"{k}\": {v}")?;
147                }
148                write!(f, "}}")
149            }
150            Value::Optional(opt) => match opt {
151                Some(v) => write!(f, "Some({v})"),
152                None => write!(f, "None"),
153            },
154            Value::Promise(state) => match state {
155                PromiseState::Pending => write!(f, "Promise<pending>"),
156                PromiseState::Resolved(v) => write!(f, "Promise<resolved: {v}>"),
157                PromiseState::Rejected(e) => write!(f, "Promise<rejected: {e}>")
158            },
159            Value::Result(res) => match res {
160                Ok(v) => write!(f, "Ok({v})"),
161                Err(e) => write!(f, "Err({e})"),
162            },
163            Value::Function { params, .. } => {
164                write!(f, "function({})", params.join(", "))
165            }
166        }
167    }
168}