aimx/values/
value.rs

1//! Runtime value representation for evaluated AIMX expressionessions.
2//!
3//! [`Value`] is the unified runtime type used by the AIMX engine. It covers
4//! literals, arrays, collections, closures, workflow/inference-specific values,
5//! and propagated errors. Conversions follow AIMX promotion rules and preserve
6//! `Errata` values.
7//!
8//! Key helpers in this module:
9//! - [`Value`]: runtime enum and conversion utilities.
10//! - [`parse_value`]: parse literal/array value syntax used by the engine.
11use crate::{
12    aim::{Prefix, PrintMode, Typedef, WriterLike, Writer},
13    expressions::{Closure, Expression},
14    literals::{Literal, parse_literal},
15    values::{Errata, Eval, Format, Instance, Node},
16};
17use anyhow::{Result, anyhow};
18use jiff::civil::DateTime;
19use nom::{
20    IResult, Parser, branch::alt, character::complete::{char, multispace0}, combinator::map, multi::many1, sequence::{delimited, preceded}
21};
22use std::cmp::Ordering;
23use std::{collections::HashMap, fmt, sync::Arc};
24use once_cell::sync::OnceCell;
25
26/// Unified runtime value used by AIMX evaluation.
27///
28/// `Value` represents evaluated data flowing through the engine: literals,
29/// arrays, collections, closures, workflow/inference types, branches, and
30/// `Errata`. Helper methods provide type inspection, conversions following
31/// AIMX rules, and formatting.
32#[derive(Debug, Clone, PartialEq)]
33pub enum Value {
34    Empty,
35    Errata(Errata),
36    Literal(Literal),
37    Array(Arc<Vec<Arc<Value>>>), // Arc-wrapped for efficient sharing
38    Collection(Arc<HashMap<Arc<str>, Arc<Expression>>>), // Arc-optimized for sharing
39    Branch(Arc<str>),
40    Closure(Arc<Closure>),
41    Eval(Eval),
42    Format(Format),
43    Instance(Instance),
44    Node(Node),
45}
46
47impl Value {
48    pub fn convert(input: Arc<str>) -> Arc<Self> {
49        match parse_value(&input) {
50            Ok((_, value)) => value,
51            _ => Arc::new(Value::Literal(Literal::Text(input))),
52        }
53    }
54
55    pub fn empty() -> Arc<Self> {
56        static GLOBAL: OnceCell<Arc<Value>> = OnceCell::new();
57        GLOBAL.get_or_init(|| Arc::new(Value::Empty)).clone()
58    }
59
60    pub fn empty_str() -> Arc<str> {
61        static GLOBAL: OnceCell<Arc<str>> = OnceCell::new();
62        GLOBAL.get_or_init(|| Arc::from("")).clone()
63    }
64
65    /// Convenience constructor for a numeric `Value`.
66    pub fn from_number(number: f64) -> Value {
67        Value::Literal(Literal::from_number(number))
68    }
69
70    /// Convenience constructor for a text `Value`.
71    pub fn from_arc_str(text: Arc<str>) -> Self {
72        Value::Literal(Literal::Text(text))
73    }
74
75    /// Return `true` if this value conforms to the given [`Typedef`].
76    pub fn is_of_type(&self, typedef: &Typedef) -> bool {
77        match self {
78            Value::Empty | Value::Errata(_) => false,
79            Value::Literal(literal) => !literal.is_empty() && typedef.is_literal() && literal.is_type(typedef),
80            Value::Array(array) => {
81                if typedef.is_any_array() {
82                    true
83                } else if array.is_empty() {
84                    false
85                } else {
86                    let literal_typedef = typedef.as_literal();
87                    array.last().unwrap().as_ref().is_of_type(&literal_typedef)
88                }
89            }
90            Value::Collection(_) => typedef.is_collection(),
91            Value::Branch(_) => typedef.is_branch(),
92            Value::Closure(_) => typedef.is_closure(),
93            Value::Eval(_) => typedef.is_eval(),
94            Value::Format(_) => typedef.is_format(),
95            Value::Instance(_) => typedef.is_instance(),
96            Value::Node(_) => typedef.is_node(),
97        }
98    }
99
100    /// Return `true` if this value's structure matches `typedef`, including nested arrays.
101
102    pub fn is_actual_type(&self, typedef: &Typedef) -> bool {
103        match self {
104            Value::Empty | Value::Errata(_) => false,
105            Value::Literal(literal) => !literal.is_empty() && typedef.is_literal() && literal.is_type(typedef),
106            Value::Array(array) => {
107                if typedef.is_any_array() {
108                    true
109                } else if typedef.is_literal() || array.is_empty() {
110                    false
111                } else {
112                    let last = array.last().unwrap().as_ref();
113                    if last.is_array() {
114                        last.is_actual_type(typedef)
115                    } else {
116                        let literal_typedef = typedef.as_literal();
117                        last.is_actual_type(&literal_typedef)
118                    }
119                }
120            }
121            Value::Collection(_) => typedef.is_collection(),
122            Value::Branch(_) => typedef.is_branch(),
123            Value::Closure(_) => typedef.is_closure(),
124            Value::Eval(_) => typedef.is_eval(),
125            Value::Format(_) => typedef.is_format(),
126            Value::Instance(_) => typedef.is_instance(),
127            Value::Node(_) => typedef.is_node(),
128        }
129    }
130
131    /// Get the type of this value.
132    ///
133    /// # Returns
134    ///
135    /// Returns a `Result<Typedef>` containing the type of this value,
136    /// or an error if this is an Empty value.
137    pub fn get_type(&self) -> Result<Typedef> {
138        match self {
139            Value::Empty => {
140                Err(anyhow!("Expecting type, found Empty"))
141            }
142            Value::Errata(_) => Err(anyhow!("Expecting type, found Error")),
143            Value::Literal(literal) => {
144                if literal.is_empty() {
145                   Err(anyhow!("Expecting type, found Empty"))
146                } else {
147                    literal.get_type()
148                }
149            }
150            Value::Array(array) => {
151                if array.is_empty() {
152                    Ok(Typedef::Array)
153                } else {
154                    let typedef = array.last().unwrap().as_ref().get_type()?;
155                    Ok(typedef.as_array())
156                }
157            }
158            Value::Collection(_) => Ok(Typedef::Collection),
159            Value::Branch(_) => Ok(Typedef::Branch),
160            Value::Closure(_) => Ok(Typedef::Closure),
161            Value::Eval(_) => Ok(Typedef::Eval),
162            Value::Format(_) => Ok(Typedef::Format),
163            Value::Instance(_) => Ok(Typedef::Instance),
164            Value::Node(_) => Ok(Typedef::Node),
165        }
166    }
167
168    /// Convert this value to match the type of `value` (based on its literal variant).
169
170    pub fn as_type(self: Arc<Value>, value: Arc<Value>) -> Result<Arc<Value>> {
171        if self.is_error() || value.is_error() {
172            return Ok(self);
173        }
174        if let Value::Literal(literal) = &*value {
175            let typedef = literal.get_type()?;
176            match typedef {
177                Typedef::Bool => return Ok(self.as_bool()),
178                Typedef::Date => return self.as_date(),
179                Typedef::Number => return self.as_number(),
180                Typedef::Task => return self.as_task(),
181                Typedef::Text => return self.as_text(),
182                _ => {}
183            }
184        }
185        Err(anyhow!("Expecting Literal, found {}", value.type_as_string()))
186    }
187
188    /// Convert this value to a specific [`Typedef`] using AIMX promotion rules.
189    ///
190
191    pub fn to_type(self: Arc<Value>, typedef: &Typedef) -> Result<Arc<Value>> {
192        // Downgrade to array
193        if self.is_array() && typedef.is_literal() {
194            let literal = self.to_literal().to_type(typedef)?;
195            Ok(Arc::new(Value::Literal(literal)))
196        } else {
197            match typedef {
198                // Literally any value
199                Typedef::Any => Ok(self),
200                // Upgrade array
201                Typedef::Array => {
202                    if self.is_array() {
203                        Ok(self)
204                    } else {
205                        Ok(self.as_array())
206                    }
207                }
208                Typedef::Bool => {
209                    if self.is_literal() {
210                        Ok(self.as_bool())
211                    } else {
212                        Ok(self.as_literal().as_bool())
213                    }
214                }
215                Typedef::BoolArray => {
216                    if self.is_array() {
217                        Ok(self.as_bool())
218                    } else {
219                        Ok(self.as_bool().as_array())
220                    }
221                }
222                Typedef::Date => self.as_date(),
223                Typedef::DateArray => {
224                    if self.is_array() {
225                        self.as_date()
226                    } else {
227                        let value = self.as_date()?;
228                        Ok(value.as_array())
229                    }
230                }
231                Typedef::Number => self.as_number(),
232                Typedef::NumberArray => {
233                    if self.is_array() {
234                        self.as_number()
235                    } else {
236                        let value = self.as_number()?;
237                        Ok(value.as_array())
238                    }
239                }
240                Typedef::Task => self.as_task(),
241                Typedef::TaskArray => {
242                    if self.is_array() {
243                        self.as_task()
244                    } else {
245                        let value = self.as_task()?;
246                        Ok(value.as_array())
247                    }
248                }
249                Typedef::Text => self.as_text(),
250                Typedef::TextArray => {
251                    if self.is_array() {
252                        self.as_text()
253                    } else {
254                        let value = self.as_text()?;
255                        Ok(value.as_array())
256                    }
257                }
258                Typedef::Closure => {
259                    if self.is_closure() {
260                        Ok(self)
261                    } else {
262                        Err(anyhow!(
263                            "Expecting Closure, found {}",
264                            self.type_as_string()
265                        ))
266                    }
267                }
268                Typedef::Collection
269                | Typedef::Branch
270                | Typedef::Retry
271                | Typedef::Eval
272                | Typedef::Format
273                | Typedef::Instance
274                | Typedef::Node => Err(anyhow!(
275                    "Invalid type conversion from {} to {}",
276                    self.type_as_string(),
277                    typedef.as_str()
278                )),
279            }
280        }
281    }
282
283    /// Check if this value is empty.
284    ///
285    /// Returns `true` if this value is the `Empty` variant, `false` otherwise.
286    ///
287
288    pub fn is_empty(&self) -> bool {
289        match self {
290            Value::Empty => true,
291            Value::Literal(literal) if literal.is_empty() => true,
292            _ => false,
293        }
294    }
295
296    /// Check if this value contains an error.
297    ///
298    /// Returns `true` if this value represents an error condition,
299    /// `false` otherwise.
300    pub fn is_error(&self) -> bool {
301        matches!(self, Value::Errata(_))
302    }
303
304    /// Check if this value is a literal.
305    ///
306    /// Returns `true` if this value is the `Literal` variant, `false` otherwise.
307    /// This includes all scalar types: booleans, numbers, text, dates, and tasks.
308    pub fn is_literal(&self) -> bool {
309        matches!(self, Value::Literal(_))
310    }
311
312    /// Check if this value is constant (immutable).
313    ///
314    /// Returns `true` if this value represents a constant value that
315    /// cannot be modified during evaluation, `false` otherwise.
316    pub fn is_constant(&self) -> bool {
317        matches!(self, Value::Literal(_) | Value::Array(_))
318    }
319
320    /// Get a reference to the literal representation of this value.
321    ///
322    /// Returns a reference to a [`Literal`] representing this value's type and content:
323    /// - For literal values, returns a reference to the embedded literal
324    /// - For arrays, returns the literal representation of the last element or `Literal::Empty` for empty arrays
325    /// - For all other value types, returns `Literal::Empty`
326    ///
327    /// This method is useful for type checking and introspection, as it provides
328    /// access to the underlying literal type without consuming the value.
329    ///
330
331    pub fn to_literal(self: Arc<Value>) -> Literal {
332        match &*self {
333            Value::Literal(literal) => literal.clone(),
334            Value::Array(array) => {
335                if array.is_empty() {
336                    Literal::Empty
337                } else {
338                    array.last().unwrap().clone().to_literal()
339                }
340            }
341            _ => Literal::Empty,
342        }
343    }
344
345    /// Convert this value to its literal representation.
346    ///
347    /// This method consumes the value and returns the underlying literal representation:
348    /// - For literal values, returns the literal itself
349    /// - For arrays, returns the last element or `Value::Empty` for empty arrays
350    /// - For all other value types, returns `Value::Empty`
351    pub fn as_literal(self: Arc<Value>) -> Arc<Value> {
352        match &*self {
353            Value::Literal(_) => self,
354            Value::Array(array) => {
355                if array.is_empty() {
356                    Value::empty()
357                } else {
358                    array.last().unwrap().clone()
359                }
360            }
361            _ => Value::empty(),
362        }
363    }
364
365    /// Check if this value is an array.
366    ///
367    /// Returns `true` if this value is the `Array` variant, `false` otherwise.
368    pub fn is_array(&self) -> bool {
369        matches!(self, Value::Array(_))
370    }
371
372    pub fn as_array(self: Arc<Value>) -> Arc<Value> {
373        // Early return if no conversion is needed
374        if self.is_empty() {
375            Value::empty()
376        } else if self.is_error() || self.is_array() {
377            self
378        } else if self.is_literal() {
379            let array: Vec<Arc<Value>> = vec![self];
380            Arc::new(Value::Array(Arc::new(array)))
381        } else {
382            Value::empty()
383        }
384    }
385
386    /// Check if this value represents a boolean.
387    ///
388    /// Returns `true` if this value is a literal boolean, `false` otherwise.
389    pub fn is_bool(&self) -> bool {
390        matches!(self, Value::Literal(literal) if literal.is_bool())
391    }
392
393    /// Convert this value to a boolean representation.
394    ///
395    /// Performs type conversion to boolean according to the AIMX grammar's
396    /// truthiness rules:
397    /// - Empty values: Always false
398    /// - Numbers: 0 is false, non-zero is true
399    /// - Text: Empty string is false, non-empty is true
400    /// - Dates: Always true (they exist)
401    /// - Arrays: Empty array is false, non-empty is true
402    /// - Tasks: Status determines value, no status is false
403    pub fn as_bool(self: Arc<Value>) -> Arc<Value> {
404        // Early return if no conversion is needed
405        match &*self {
406            Value::Empty | Value::Errata(_) => return self,
407            Value::Literal(literal) if literal.is_empty() => return Value::empty(),
408            Value::Literal(literal) if literal.is_bool() => return self,
409            _ => {}
410        }
411        // Now do the conversion for cases that need it
412        match &*self {
413            Value::Literal(literal) => Arc::new(Value::Literal(literal.clone().as_bool())),
414            Value::Array(array) => {
415                let bool_array = (*array)
416                    .iter()
417                    .map(|value| {
418                        if value.is_bool() {
419                            value.clone()
420                        } else {
421                            value.clone().as_bool()
422                        }
423                    })
424                    .collect();
425                Arc::new(Value::Array(Arc::new(bool_array)))
426            }
427            _ => Value::empty(),
428        }
429    }
430
431    pub fn to_bool(self: Arc<Value>) -> Arc<Value> {
432        // Early return if no conversion is needed
433        match &*self {
434            Value::Empty | Value::Errata(_) => return self,
435            Value::Literal(literal) if literal.is_empty() => return Value::empty(),
436            Value::Literal(literal) if literal.is_bool() => return self,
437            _ => {}
438        }
439        // Now do the conversion for cases that need it
440        match &*self {
441            Value::Literal(literal) => Arc::new(Value::Literal(literal.clone().as_bool())),
442            Value::Array(array) => {
443                if array.is_empty() {
444                    Value::empty()
445                } else {
446                    array.last().unwrap().clone().to_bool()
447                }
448            }
449            _ => Value::empty(),
450        }
451    }
452
453    /// Check if this value represents a date.
454    ///
455    /// Returns `true` if this value is a literal date, `false` otherwise.
456    pub fn is_date(&self) -> bool {
457        matches!(self, Value::Literal(literal) if literal.is_date())
458    }
459
460    /// Convert this value to a date representation.
461    ///
462    /// Attempts to convert the value to a date according to the AIMX grammar's
463    /// conversion rules:
464    /// - Empty values: Remain empty (no conversion needed)
465    /// - Dates: No conversion needed
466    /// - Text: Parsed as date if possible (e.g., "2023-01-01")
467    /// - Number: Interpreted as Unix timestamp
468    /// - Boolean: true becomes Unix epoch + 1 second, false becomes Unix epoch
469    /// - Task: Text component parsed as date if possible
470    ///
471    /// # Returns
472    ///
473    /// Returns a `Result<Value>` containing the converted date value or an error
474    /// if conversion is not possible.
475    pub fn as_date(self: Arc<Value>) -> Result<Arc<Value>> {
476        // Early return if no conversion is needed
477        match &*self {
478            Value::Empty | Value::Errata(_) => return Ok(self),
479            Value::Literal(literal) if literal.is_empty() => return Ok(Value::empty()),
480            Value::Literal(literal) if literal.is_date() => return Ok(self),
481            _ => {}
482        }
483        // Now do the conversion for cases that need it
484        Ok(Arc::new(match &*self {
485            Value::Literal(literal) => Value::Literal(literal.clone().as_date()?),
486            Value::Array(array) => {
487                let date_array: Result<Vec<Arc<Value>>, anyhow::Error> = (*array)
488                    .iter()
489                    .map(|value| {
490                        if value.is_date() {
491                            Ok(value.clone())
492                        } else {
493                            let date_value = value.clone().as_date()?;
494                            Ok(date_value)
495                        }
496                    })
497                    .collect();
498                Value::Array(Arc::new(date_array?))
499            }
500            _ => return Err(anyhow!("Cannot convert {} to Date", self.type_as_string())),
501        }))
502    }
503
504    /// Check if this value represents a number.
505    ///
506    /// Returns `true` if this value is a literal number, `false` otherwise.
507    pub fn is_number(&self) -> bool {
508        matches!(self, Value::Literal(literal) if literal.is_number())
509    }
510
511    /// Convert this value to a number representation.
512    ///
513    /// Attempts to convert the value to a number according to the AIMX grammar's
514    /// conversion rules:
515    /// - Empty values: Remain empty (no conversion needed)
516    /// - Numbers: No conversion needed
517    /// - Text: Parsed as number if it represents a valid numeric literal (e.g., "42", "3.14")
518    /// - Boolean: false becomes 0, true becomes 1
519    /// - Date: Converted to Unix timestamp
520    /// - Task: Status determines value (true=1, false=-1, none=0)
521    ///
522    /// # Returns
523    ///
524    /// Returns a `Result<Value>` containing the converted number value or an error
525    /// if conversion is not possible.
526    pub fn as_number(self: Arc<Value>) -> Result<Arc<Value>> {
527        // Early return if no conversion is needed
528        match &*self {
529            Value::Empty | Value::Errata(_) => return Ok(self),
530            Value::Literal(literal) if literal.is_empty() => return Ok(Value::empty()),
531            Value::Literal(literal) if literal.is_number() => return Ok(self),
532            _ => {}
533        }
534        // Now do the conversion for cases that need it
535        Ok(Arc::new(match &*self {
536            Value::Literal(literal) => Value::Literal(literal.clone().as_number()?),
537            Value::Array(array) => {
538                let number_array: Result<Vec<Arc<Value>>, anyhow::Error> = (*array)
539                    .iter()
540                    .map(|value| {
541                        if value.is_number() {
542                            Ok(value.clone())
543                        } else {
544                            let converted_value = value.clone().as_number()?;
545                            Ok(converted_value)
546                        }
547                    })
548                    .collect();
549                Value::Array(Arc::new(number_array?))
550            }
551            _ => {
552                return Err(anyhow!(
553                    "Cannot convert {} to Number",
554                    self.type_as_string()
555                ));
556            }
557        }))
558    }
559
560    /// Extract a numeric value from this value.
561    ///
562    /// This is a convenience method for when you specifically need a `f64` number.
563    /// It's particularly useful for arithmetic operations and mathematical functions.
564    ///
565    /// # Returns
566    ///
567    /// Returns a `Result<f64>` containing the numeric value or an error if:
568    /// - The value is empty
569    /// - The value is an array with no elements
570    /// - The underlying literal cannot be converted to a number
571    pub fn to_number(&self) -> Result<f64> {
572        match self {
573            Value::Literal(literal) => literal.to_number(),
574            Value::Array(array) => {
575                if array.is_empty() {
576                    Err(anyhow!("Cannot convert empty Array to Number"))
577                } else {
578                    let value = array.last().unwrap().clone(); 
579                    value.to_number()
580                }
581            }
582            _ => Err(anyhow!(
583                "Cannot convert {} to Number",
584                self.type_as_string()
585            )),
586        }
587    }
588
589    /// Check if this value represents a task.
590    ///
591    /// Returns `true` if this value is a literal task, `false` otherwise.
592    pub fn is_task(&self) -> bool {
593        matches!(self, Value::Literal(literal) if literal.is_task())
594    }
595
596    /// Convert this value to a task representation.
597    ///
598    /// Attempts to convert the value to a task according to the AIMX grammar's
599    /// conversion rules:
600    /// - Empty values: Remain empty (no conversion needed)
601    /// - Tasks: No conversion needed
602    /// - Boolean: Status becomes the boolean value, text becomes "true"/"false"
603    /// - Date: No status, text becomes date string
604    /// - Number: Status based on sign (positive=true, negative=false, zero=none), text becomes number string
605    /// - Text: No status, text remains the same
606    ///
607    /// # Returns
608    ///
609    /// Returns a `Result<Value>` containing the converted task value or an error
610    /// if conversion is not possible.
611    pub fn as_task(self: Arc<Value>) -> Result<Arc<Value>> {
612        // Early return if no conversion is needed
613        match &*self {
614            Value::Empty | Value::Errata(_) => return Ok(self),
615            Value::Literal(literal) if literal.is_empty() => return Ok(Value::empty()),
616            Value::Literal(literal) if literal.is_task() => return Ok(self),
617            _ => {}
618        }
619        // Now do the conversion for cases that need it
620        Ok(Arc::new(match &*self {
621            Value::Literal(literal) => Value::Literal(literal.clone().as_task()?),
622            Value::Array(array) => {
623                let task_array: Result<Vec<Arc<Value>>, anyhow::Error> = (*array)
624                    .iter()
625                    .map(|value| {
626                        if value.is_task() {
627                            Ok(value.clone())
628                        } else {
629                            let converted_value = value.clone().as_task()?;
630                            Ok(converted_value)
631                        }
632                    })
633                    .collect();
634                Value::Array(Arc::new(task_array?))
635            }
636            _ => return Err(anyhow!("Cannot convert {} to Task", self.type_as_string())),
637        }))
638    }
639
640    /// Check if this value represents text.
641    ///
642    /// Returns `true` if this value is a literal text, `false` otherwise.
643    pub fn is_text(&self) -> bool {
644        matches!(self, Value::Literal(literal) if literal.is_text())
645    }
646
647    /// Convert this value to a text representation.
648    ///
649    /// Converts the value to text according to the AIMX grammar's conversion rules:
650    /// - Empty values: Remain empty (no conversion needed)
651    /// - Text: No conversion needed
652    /// - Boolean: "true" or "false"
653    /// - Date: Formatted as ISO 8601 date string (e.g., "2023-01-01T00:00:00.000")
654    /// - Number: Formatted as string (e.g., "42", "3.14")
655    /// - Task: Text component of the task (status is preserved in the Value but not in the text conversion)
656    ///
657    /// # Returns
658    ///
659    /// Returns a `Result<Value>` containing the converted text value or an error
660    /// if conversion is not possible.
661    pub fn as_text(self: Arc<Value>) -> Result<Arc<Value>> {
662        // Early return if no conversion is needed
663        match &*self {
664            Value::Empty | Value::Errata(_) => return Ok(self),
665            Value::Literal(literal) if literal.is_empty() => return Ok(Value::empty()),
666            Value::Literal(literal) if literal.is_text() => return Ok(self),
667            _ => {}
668        }
669        // Now do the conversion for cases that need it
670        Ok(Arc::new(match &*self {
671            Value::Literal(literal) => Value::Literal(literal.clone().as_text()?),
672            Value::Array(array) => {
673                let text_array: Result<Vec<Arc<Value>>, anyhow::Error> = (*array)
674                    .iter()
675                    .map(|value| {
676                        if value.is_text() {
677                            Ok(value.clone())
678                        } else {
679                            let converted_value = value.clone().as_text()?;
680                            Ok(converted_value)
681                        }
682                    })
683                    .collect();
684                Value::Array(Arc::new(text_array?))
685            }
686            _ => return Err(anyhow!("Cannot convert {} to Text", self.type_as_string())),
687        }))
688    }
689
690    pub fn to_arc_str(&self) -> Arc<str> {
691        match self {
692            Value::Literal(Literal::Text(text))
693            | Value::Literal(Literal::Task(_, text)) => text.clone(),
694            _ => Arc::from(self.to_string()),
695        }
696    }
697
698    /// Check if this value represents a closure.
699    ///
700    /// Returns `true` if this value is a closure, `false` otherwise.
701    pub fn is_closure(&self) -> bool {
702        matches!(self, Value::Closure(_))
703    }
704
705    /// Check if this value represents a branch.
706    ///
707    /// Returns `true` if this value is a branch, `false` otherwise.
708    pub fn is_branch(&self) -> bool {
709        matches!(self, Value::Branch(_))
710    }
711
712    /// Check if this value represents an eval.
713    ///
714    /// Returns `true` if this value is an eval, `false` otherwise.
715    pub fn is_eval(&self) -> bool {
716        matches!(self, Value::Eval(_))
717    }
718
719    pub fn to_pass(&self) -> Result<Value> {
720        match self {
721            Value::Eval(eval) => Ok(eval.to_pass()),
722            _ => Err(anyhow!("Expecting Eval, found {}", self.type_as_string()))
723        }
724    }
725
726    pub fn to_fail(&self) -> Result<Value> {
727        match self {
728            Value::Eval(eval) => Ok(eval.to_fail()),
729            _ => Err(anyhow!("Expecting Eval, found {}", self.type_as_string()))
730        }
731    }
732
733    /// Check if this value represents a format.
734    ///
735    /// Returns `true` if this value is a format, `false` otherwise.
736    pub fn is_format(&self) -> bool {
737        matches!(self, Value::Format(_))
738    }
739
740    /// Check if this value represents an instance.
741    ///
742    /// Returns `true` if this value is an instance, `false` otherwise.
743    pub fn is_instance(&self) -> bool {
744        matches!(self, Value::Instance(_))
745    }
746
747    pub fn get_instance(&self) -> Option<Instance> {
748        match self {
749            Value::Instance(instance) => Some(instance.clone()),
750            _ => None,
751        }
752    }
753
754    /// Check if this value represents a node.
755    ///
756    /// Returns `true` if this value is a node, `false` otherwise.
757    pub fn is_node(&self) -> bool {
758        matches!(self, Value::Node(_))
759    }
760
761    pub fn get_node(&self) -> Option<Node> {
762        match self {
763            Value::Node(node) => Some(node.clone()),
764            _ => None,
765        }
766    }
767
768    /// Get Arc-wrapped collection if this is a collection value.
769    ///
770    /// Returns an `Arc<HashMap<String, Arc<Expression>>>` if this is a collection,
771    /// allowing cheap cloning and shared access.
772    pub fn as_collection_arc(&self) -> Option<Arc<HashMap<Arc<str>, Arc<Expression>>>> {
773        match self {
774            Value::Collection(collection) => Some(collection.clone()),
775            _ => None,
776        }
777    }
778
779    /// Get Arc-wrapped collection reference if this is a collection value.
780    ///
781    /// Returns a reference to the internal `Arc<HashMap<String, Arc<Expression>>>`
782    /// without cloning, for direct access when you need to avoid ownership transfer.
783    pub fn get_collection_ref(&self) -> Option<&Arc<HashMap<Arc<str>, Arc<Expression>>>> {
784        match self {
785            Value::Collection(collection) => Some(collection),
786            _ => None,
787        }
788    }
789
790    /// Get a string representation of this value's type. Used to provide type information
791    /// in error messages.
792    ///
793    /// Returns a string indicating the type of this value based on its underlying literal
794    /// representation. Possible return values are: "Empty", "Error", "Bool", "Date", "Number",
795    /// "Task", "Text", "Closure", "Node".
796    pub fn type_as_string(&self) -> &'static str {
797        match self {
798            Value::Empty => "Empty",
799            Value::Errata(_) => "Error",
800            Value::Literal(literal) => literal.type_as_string(),
801            Value::Array(array) => {
802                if array.is_empty() {
803                    "Empty"
804                } else {
805                    array.last().unwrap().as_ref().type_as_string()
806                }
807            }
808            Value::Collection(_) => "Collection",
809            Value::Branch(_) => "Branch",
810            Value::Closure(_) => "Closure",
811            Value::Eval(_) => "Eval",
812            Value::Format(_) => "Format",
813            Value::Instance(_) => "Instance",
814            Value::Node(_) => "Node",
815        }
816    }
817
818    // Helper function to get type order for consistent sorting
819    fn type_order(&self) -> u8 {
820        match self {
821            Value::Empty => 0,
822            Value::Errata(_) => 1,
823            Value::Node(_) => 2,
824            Value::Instance(_) => 3,
825            Value::Format(_) => 4,
826            Value::Eval(_) => 5,
827            Value::Closure(_) => 6,
828            Value::Branch(_) => 7,
829            Value::Collection(_) => 8,
830            Value::Literal(_) => 9,
831            Value::Array(_) => 10,
832        }
833    }
834
835    /// Write this value to the provided writer using the appropriate formatting.
836    ///
837    /// This implementation delegates to the writer's `print_value` method,
838    /// which handles the formatting based on the writer's mode (string, sanitized, formula).
839    ///
840    /// # Arguments
841    ///
842    /// * `writer` - The writer to write to
843    pub fn print(&self, writer: &mut Writer) {
844        let prefix = writer.prefix();
845        self.pretty_print(&prefix, writer);
846    }
847
848    /// Print this this value using the given `Prefix`.
849    pub fn pretty_print(&self, prefix: &Prefix, writer: &mut Writer) {
850         match self {
851            Value::Empty => {}
852            Value::Errata(errata) => errata.print(writer),
853            Value::Literal(literal) => literal.print(writer),
854            Value::Array(_) | Value::Collection(_) => {
855                match writer.print_mode() {
856                    PrintMode::None => self.stringize(-1, prefix, 0, writer),
857                    PrintMode::Escape => self.sanitize(-1, prefix, 0, writer),
858                    PrintMode::QuoteEscape
859                    | PrintMode::DoubleQuoteEscape => self.formulize(0, writer),
860                }
861                
862            }
863            Value::Branch(identifier) => writer.write_str(identifier),
864            Value::Closure(closure) => closure.print(writer),
865            Value::Eval(eval) => eval.print(writer),
866            Value::Format(format) => format.print(writer),
867            Value::Instance(instance) => instance.print(writer),
868            Value::Node(node) => node.print(writer),
869        }
870    }
871
872    fn stringize(&self, indent: isize, prefix: &Prefix, index: usize, writer: &mut Writer) {
873        match self {
874            Value::Array(array) => {
875                for (n, value) in array.iter().enumerate() {
876                    if n > 0 {
877                        writer.write_eol();
878                    }
879                    value.stringize(indent + 1, prefix, n, writer);
880                }
881            }
882            Value::Collection(pool) => {
883                for (n, (key, expression)) in pool.iter().enumerate() {
884                    if n > 0 {
885                        writer.write_eol();
886                    }
887                    writer.write_prefix(indent, prefix, n);
888                    writer.write_str(key);
889                    writer.write_str(": ");
890                    expression.write(writer);
891                }
892            }
893            _ => {
894                if indent >= 0 {
895                    writer.write_prefix(indent, prefix, index);
896                }
897                self.print(writer);
898            }
899       }
900    }
901
902    fn sanitize(&self, indent: isize, prefix: &Prefix, index: usize, writer: &mut Writer) {
903        match self {
904            Value::Array(array) => {
905                for (n, value) in array.iter().enumerate() {
906                    if n > 0 {
907                        writer.write_str("\\n");
908                    }
909                    value.sanitize(indent + 1, prefix, n, writer);
910                }
911            }
912            Value::Collection(pool) => {
913                for (index, (key, expression)) in pool.iter().enumerate() {
914                    if index > 0 {
915                        writer.write_str("\\n");
916                    }
917                    writer.write_prefix(0, prefix, index);
918                    writer.escape(key);
919                    writer.write_str(": ");
920                    expression.write(writer);
921                }
922            }
923            _ => {
924                if indent >= 0 {
925                    writer.write_prefix(indent, prefix, index);
926                }
927                self.print(writer);
928            }
929        }
930    }
931
932    fn formulize(&self, indent: usize, writer: &mut Writer) {
933        match self {
934            Value::Array(array) => {
935                if indent > 0 {
936                    writer.write_char('(');
937                }
938                for (n, value) in array.iter().enumerate() {
939                    if n > 0 {
940                        writer.write_str(", ");
941                    }
942                    value.formulize(indent + 1, writer);
943                }
944                if indent > 0 {
945                    writer.write_char(')');
946                }
947            }
948            Value::Collection(pool) => {
949                writer.write_char('{');
950                let mut first = true;
951                for (key, expression) in pool.iter() {
952                    if !first {
953                        writer.write_str("; ");
954                    }
955                    first = false;
956                    writer.quote_escape(key);
957                    writer.write_str(" = ");
958                    expression.write(writer);
959                }
960                writer.write_char('}');
961            }
962            _ => self.print(writer),
963        }
964    }
965
966    /// Format this value to a pretty string using the given `Prefix`.
967    pub fn to_pretty_str(&self, prefix: Prefix) -> Arc<str> {
968        let mut writer = Writer::new(PrintMode::None, prefix);
969        self.pretty_print(&prefix, &mut writer);
970        Arc::from(writer.finish())
971    }
972
973    /// Return the formula-string representation (round-trippable by the parser).
974    pub fn to_formula(&self) -> String {
975        let mut writer = Writer::formulizer();
976        self.print(&mut writer);
977        writer.finish()
978    }
979}
980
981impl WriterLike for Value {
982    fn write(&self, writer: &mut Writer) {
983        self.print(writer);
984    }
985}
986
987impl fmt::Display for Value {
988    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989        write!(f, "{}", self.to_stringized())
990    }
991}
992
993impl PartialOrd for Value {
994    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
995        // Define a consistent ordering by type first, then value
996        // Type ordering: Empty < Bool < Number < Date < Task < Text
997        let self_type_order = self.type_order();
998        let other_type_order = other.type_order();
999        if self_type_order > other_type_order {
1000            Some(Ordering::Greater)
1001        } else if self_type_order < other_type_order {
1002            Some(Ordering::Less)
1003        } else {
1004            match (self, other) {
1005                // Start by assuming the types match
1006                (Value::Empty, Value::Empty) => Some(Ordering::Equal),
1007                (Value::Literal(a), Value::Literal(b)) => a.partial_cmp(b),
1008                (Value::Array(a), Value::Array(b)) => {
1009                    // Compare arrays element by element
1010                    let len_a = a.len();
1011                    let len_b = b.len();
1012                    let min_len = std::cmp::min(len_a, len_b);
1013
1014                    for i in 0..min_len {
1015                        match a[i].partial_cmp(&b[i]) {
1016                            Some(Ordering::Equal) => continue,
1017                            other => return other,
1018                        }
1019                    }
1020
1021                    // If all compared elements are equal, compare by length
1022                    len_a.partial_cmp(&len_b)
1023                }
1024                _ => Some(Ordering::Equal),
1025            }
1026        }
1027    }
1028}
1029
1030impl Eq for Value {}
1031
1032impl Ord for Value {
1033    fn cmp(&self, other: &Self) -> Ordering {
1034        self.partial_cmp(other).unwrap()
1035    }
1036}
1037
1038fn parse_comma(input: &str) -> IResult<&str, Arc<Value>> {
1039    preceded(
1040        (multispace0, char(','), multispace0),
1041        alt((
1042            parse_value_array,
1043            map(parse_literal, |l| Arc::new(Value::Literal(l))),
1044        ))
1045    ).parse(input)
1046}
1047
1048/// Parse a parenthesis-enclosed literal/array value used by `parse_value`.
1049fn parse_value_array(input: &str) -> IResult<&str, Arc<Value>> {
1050    let (input, value) = delimited(char('('), parse_value, char(')')).parse(input)?;
1051    let value = match value.clone().as_ref() {
1052        Value::Empty => Arc::new(Value::Array(Arc::new(Vec::new()))),
1053        Value::Literal(_) => Arc::new(Value::Array(Arc::new(vec![value]))),
1054        _ => value,
1055    };
1056    Ok((input, value))
1057}
1058
1059/// Parse a value from AIMX value syntax (literals or parenthesized lists).
1060pub fn parse_value(input: &str) -> IResult<&str, Arc<Value>> {
1061    let input = input.trim();
1062    // Value is empty
1063    if input.is_empty() {
1064        return Ok((input, Value::empty()));
1065    }
1066    // Parenthesis enclosed array
1067    let (input, first) = if input.starts_with('(') {
1068        parse_value_array(input)
1069    } else {
1070        match parse_literal(input) {
1071            Ok((remain, literal)) => Ok((remain, Arc::new(Value::Literal(literal)))),
1072            _ => Ok((input, Value::empty())),
1073        }
1074    }?;
1075    if let Ok((input, value_list)) = many1(parse_comma).parse(input) {
1076        let mut array = vec![first];
1077        for conditional in value_list {
1078            array.push(conditional);
1079        }
1080        let (input, _) = multispace0(input)?;
1081        Ok((input, Arc::new(Value::Array(Arc::new(array)))))
1082    } else {
1083        let (input, _) = multispace0(input)?;
1084        Ok((input, first))
1085    }
1086}
1087
1088impl From<f64> for Value {
1089    fn from(n: f64) -> Self {
1090        Value::Literal(Literal::Number(n))
1091    }
1092}
1093
1094impl From<Arc<str>> for Value {
1095    fn from(s: Arc<str>) -> Self {
1096        Value::Literal(Literal::Text(s))
1097    }
1098}
1099
1100impl From<bool> for Value {
1101    fn from(b: bool) -> Self {
1102        Value::Literal(Literal::Bool(b))
1103    }
1104}
1105
1106impl From<DateTime> for Value {
1107    fn from(d: DateTime) -> Self {
1108        Value::Literal(Literal::Date(d))
1109    }
1110}
1111
1112impl From<Vec<f64>> for Value {
1113    fn from(array: Vec<f64>) -> Self {
1114        let result: Vec<Arc<Value>> = array
1115            .iter()
1116            .map(|n| Arc::new(Value::Literal(Literal::Number(*n))))
1117            .collect();
1118        Value::Array(Arc::new(result))
1119    }
1120}
1121
1122impl From<Vec<Arc<str>>> for Value {
1123    fn from(array: Vec<Arc<str>>) -> Self {
1124        let result: Vec<Arc<Value>> = array
1125            .iter()
1126            .map(|s| Arc::new(Value::Literal(Literal::Text(s.clone()))))
1127            .collect();
1128        Value::Array(Arc::new(result))
1129    }
1130}
1131
1132impl From<Vec<bool>> for Value {
1133    fn from(array: Vec<bool>) -> Self {
1134        let result: Vec<Arc<Value>> = array
1135            .iter()
1136            .map(|b| Arc::new(Value::Literal(Literal::Bool(*b))))
1137            .collect();
1138        Value::Array(Arc::new(result))
1139    }
1140}
1141
1142impl From<Vec<DateTime>> for Value {
1143    fn from(array: Vec<DateTime>) -> Self {
1144        let result: Vec<Arc<Value>> = array
1145            .iter()
1146            .map(|d| Arc::new(Value::Literal(Literal::Date(*d))))
1147            .collect();
1148        Value::Array(Arc::new(result))
1149    }
1150}