aimx/
value.rs

1//! Runtime value representation for AIM Expressions (AIMX).
2//!
3//! This module defines the [`Value`] enum that represents runtime values produced
4//! during expression evaluation. The `Value` type serves as the primary data
5//! structure that flows through the expression evaluation engine, representing
6//! all possible data types that can be manipulated by AIMX expressions.
7//!
8//! Unlike the compile-time [`Literal`] enum which represents static values,
9//! `Value` can represent dynamically evaluated results, arrays of values,
10//! closures, and special workflow-related types. This makes it the central
11//! runtime entity for the entire AIMX evaluation system.
12//!
13//! # Design Philosophy
14//!
15//! The `Value` type is designed with several core principles in mind:
16//! - **Tree-like Structure**: Values form a tree where arrays can contain other values, enabling
17//!   complex data representations.
18//! - **Type Safety**: Comprehensive type checking and conversion capabilities following AIMX grammar rules
19//! - **Error Handling**: First-class error values that preserve diagnostic information throughout evaluation
20//! - **Memory Efficiency**: Recursive data structures are boxed to prevent stack overflow
21//! - **Thread Safety**: Values can be safely used across threads in concurrent workflows
22//!
23//! # Key Features
24//!
25//! - **Comprehensive Type System**: Supports all AIMX data types including literals,
26//!   arrays, closures, and workflow-specific types
27//! - **Automatic Type Conversion**: Provides intuitive type promotion and conversion
28//!   methods following AIMX grammar rules
29//! - **Tree-like Structure**: Arrays can contain other values, allowing nested and
30//!   complex data representations
31//! - **Error Handling**: Includes error values that capture evaluation failures
32//! - **Workflow Integration**: Supports workflow-specific types like nodes, format,
33//!   and eval for agentic workflow applications
34//!
35//! # Core Concepts
36//!
37//! ## Value Hierarchy
38//!
39//! The `Value` enum represents a unified type hierarchy where all values can be categorized into:
40//! - **Base Values**: Empty, Error, and Literal values represent atomic values
41//! - **Composite Values**: Arrays and closures enable structured and functional programming
42//! - **Special Values**: Workflow-specific types for inference functionality
43//!
44//! # Types and Variants
45//!
46//! The `Value` enum encompasses all possible runtime data types in the AIMX system:
47//!
48//! ## Base Values
49//! - **Array**: Collections of values, allowing for nested data structures
50//! - **Closure**: First-class anonymous functions for functional programming
51//! - **Empty**: Represents an empty or uninitialized value
52//! - **Errata**: Captures expression and evaluation error conditions with diagnostic information
53//! - **Literal**: Encapsulates literal values (Bool, Date, Number, Task, Text)
54//!
55//! ## Special Values
56//! - **Assignment**: Variable references for workflow assignments
57//! - **Format**: Inference output formatting data
58//! - **Eval**: Inference evaluation data
59//! - **Node**: References to workflow files and nodes
60//!
61//! # Examples
62//!
63//! ## Creating Values
64//!
65//! ```rust
66//! use aimx::{Value, Literal};
67//!
68//! // Creating different types of values
69//! let empty_value = Value::Empty;
70//! let literal_value = Value::Literal(Literal::from_number(42.0));
71//! let array_value = Value::Array(vec![
72//!     Box::new(Value::Literal(Literal::from_text("hello".to_string()))),
73//!     Box::new(Value::Literal(Literal::from_number(123.0)))
74//! ]);
75//!
76//! // Checking value types
77//! assert!(empty_value.is_empty());
78//! assert!(literal_value.is_literal());
79//! assert!(literal_value.is_number());
80//! assert!(array_value.is_array());
81//!
82//! // Converting values
83//! let num_as_text = literal_value.clone().as_text().unwrap();
84//! assert!(num_as_text.is_text());
85//! ```
86//!
87//! ## Using Values in Expression Evaluation
88//!
89//! ```rust
90//! use aimx::{Value, Literal, ExpressionLike, Context, Reference, ContextLike};
91//!
92//! let mut context = aimx::Context::new();
93//! 
94//! // For this example, we'll just demonstrate creating and using values
95//! let price_value = Value::Literal(Literal::from_number(100.0));
96//! let tax_rate_value = Value::Literal(Literal::from_number(0.08));
97//! 
98//! // Calculate total: price * (1 + tax_rate)
99//! let total = 100.0 * (1.0 + 0.08);
100//! assert_eq!(total, 108.0);
101//! ```
102//!
103//! ## Type Conversion Examples
104//!
105//! ```rust
106//! use aimx::{Value, Literal};
107//!
108//! // Type promotion in expressions
109//! let number_value = Value::Literal(Literal::from_number(42.0));
110//! 
111//! // Convert number to text
112//! let text_value = number_value.clone().as_text().unwrap();
113//! assert!(text_value.is_text());
114//! 
115//! // Convert number to boolean (truthiness)
116//! let bool_value = number_value.clone().as_bool();
117//! assert!(bool_value.to_literal().to_bool());
118//! 
119//! // Convert number to date (Unix timestamp)
120//! let date_value = number_value.as_date().unwrap();
121//! assert!(date_value.is_date());
122//! ```
123//!
124//! ## Working with Arrays
125//!
126//! ```rust
127//! use aimx::{Value, Literal};
128//!
129//! // Create nested arrays
130//! let nested_array = Value::Array(vec![
131//!     Box::new(Value::Literal(Literal::from_text("first".to_string()))),
132//!     Box::new(Value::Array(vec![
133//!         Box::new(Value::Literal(Literal::from_number(1.0))),
134//!         Box::new(Value::Literal(Literal::from_number(2.0)))
135//!     ]))
136//! ]);
137//!
138//! // Check array properties
139//! assert!(nested_array.is_array());
140//! 
141//! // Convert single value to array
142//! let single_value = Value::Literal(Literal::from_number(42.0));
143//! let as_array = single_value.as_array();
144//! assert!(as_array.is_array());
145//! ```
146//!
147//! # Type Conversion Rules
148//!
149//! AIMX follows intuitive type conversion rules when values need to be promoted
150//! to different types. The conversion methods (`as_text`, `as_number`, etc.) follow
151//! these principles:
152//!
153//! - **Type Promotion Strategy**: Left-operand-first promotion where the left operand's type
154//!   dictates how the right operand is converted
155//! - **Error Handling**: Conversion operations gracefully handle invalid conversions by returning
156//!   appropriate error values or `Result` types
157//! - **Idempotency**: Converting a value to its own type typically returns the value unchanged
158//!
159//! - **Empty values** remain empty in most conversions
160//! - **Booleans**: `true`/`false` values maintain their semantic meaning
161//! - **Numbers**: Numeric values can be converted to text, dates, or tasks
162//! - **Text**: String values can be parsed into numbers, dates, or remain as text
163//! - **Dates**: Date values can be converted to timestamps or formatted text
164//! - **Tasks**: Task values preserve their status and description semantics
165//! - **Arrays**: Conversions are applied element-wise to array contents
166//!
167//! # Implementation Details
168//!
169//! The `Value` enum forms the foundation of the AIMX runtime system. It supports:
170//! - **AIMX Grammar Compliance**: All conversion rules match the AIMX specification
171//! - **Memory Efficiency**: Uses `Box<Value>` for recursive data structures to avoid stack overflow
172//! - **Thread Safety**: Can be safely used across threads in concurrent scenarios
173//! - **Serialization**: Provides formatting methods for different display contexts
174//!
175//! # See Also
176//!
177//! - [`Literal`] - Compile-time fixed value representations
178//! - [`ExpressionLike`] - Trait for expression evaluation
179//! - [`ContextLike`] - Evaluation context interface
180//! - [`Value` parsing](parse_value) - Function to parse value literals from text
181use nom::{
182    IResult,
183    Parser,
184    character::complete::{char, multispace0},
185    multi::many1,
186    sequence::delimited,
187};
188use crate::{
189    ContextLike,
190    expressions::Closure,
191    Reference,
192    ExpressionLike,
193    parse_literal,
194    Literal,
195    Node,
196    values::{Errata, Eval, Format},
197    Typedef,
198    Prefix,
199    PrintMode,
200    Writer,
201};
202use std::fmt;
203use std::cmp::Ordering;
204use anyhow::{anyhow, Result};
205
206/// Runtime value representation during expression evaluation.
207///
208/// This enum encapsulates all possible runtime values that can result from
209/// evaluating expressions in the AIMX language. Values are produced when expressions
210/// are evaluated within a context and represent the actual data that flows through
211/// the expression evaluation engine.
212///
213/// The `Value` type forms a tree-like structure where arrays can contain other values,
214/// allowing for nested and complex data representations. This is the primary data
215/// structure used throughout the evaluation phase of the expression engine.
216///
217/// # Variants
218///
219/// - **Empty** - Represents an empty or uninitialized value, typically used as a placeholder
220///   or result of operations that return no meaningful data
221/// - **Errata(Errata)** - Contains evaluation errors with detailed context information
222/// - **Literal(Literal)** - A single literal value (boolean, number, text, date, or task)
223/// - **Array(`Vec<Box<Value>>`)** - An array of values, allowing for collections of data
224/// - **Closure(Closure)** - A first-class anonymous function for functional programming
225/// - **Assignment(Reference)** - A variable reference used for workflow assignments
226/// - **Format(Format)** - Inference output formatting data for agentic workflows
227/// - **Eval(Eval)** - Inference evaluation data for agentic workflows
228/// - **Node(Node)** - A reference to a workflow file or node
229///
230/// # Type Hierarchy
231///
232/// The `Value` enum represents the runtime counterpart to the compile-time [`Typedef`] enum.
233/// While [`Typedef`] represents type definitions, `Value` represents actual runtime data
234/// that conforms to those types.
235///
236/// # Examples
237///
238/// ## Creating Values
239///
240/// ```rust
241/// use aimx::{Value, Literal};
242///
243/// // Creating different value types
244/// let empty = Value::Empty;
245/// let number = Value::Literal(Literal::from_number(42.0));
246/// let text = Value::Literal(Literal::from_text("Hello".to_string()));
247/// let array = Value::Array(vec![
248///     Box::new(Value::Literal(Literal::from_number(1.0))),
249///     Box::new(Value::Literal(Literal::from_number(2.0))),
250///     Box::new(Value::Literal(Literal::from_number(3.0))),
251/// ]);
252///
253/// // Type checking
254/// assert!(empty.is_empty());
255/// assert!(number.is_number());
256/// assert!(text.is_text());
257/// assert!(array.is_array());
258///
259/// // Converting between types
260/// let text_from_number = number.clone().as_text().unwrap();
261/// assert!(text_from_number.is_text());
262/// ```
263///
264/// ## Using Values in Workflow Context
265///
266/// ```rust
267/// use aimx::{Value, Literal, Context, Reference, ContextLike};
268///
269/// let mut context = aimx::Context::new();
270/// 
271/// // Use assignment references for inference results
272/// let assignment = Value::Assignment(aimx::Reference::new("_result"));
273/// 
274/// // Use closure for functional programming (simplified example)
275/// // In practice, closures are parsed from expressions like "x => x * 2"
276/// ```
277///
278/// ## Type Conversions
279///
280/// Values can be converted between different types using the `as_*` methods:
281///
282/// ```rust
283/// use aimx::{Value, Literal};
284///
285/// let value = Value::Literal(Literal::from_number(42.0));
286/// let as_text = value.clone().as_text().unwrap();
287/// assert!(as_text.is_text());
288/// 
289/// let as_bool = value.as_bool();
290/// assert!(as_bool.is_bool());
291/// ```
292///
293/// # Implementation Notes
294///
295/// - **Memory Management**: Arrays use `Box<Value>` to avoid infinite recursion and stack overflow
296/// - **Error Handling**: The `Errata` variant captures detailed error information for debugging
297/// - **Workflow Integration**: Special variants like `Node`, `Format`, and `Eval` support agentic workflows
298/// - **Type Safety**: All conversion methods return `Result` types to handle conversion failures gracefully
299///
300/// # See Also
301///
302/// - [`Literal`] - Compile-time literal value representation
303/// - [`Typedef`] - Type definition system
304/// - [`ExpressionLike`] - Trait for expression evaluation
305/// - [`ContextLike`] - Evaluation context interface
306#[derive(Debug, Clone, PartialEq)]
307pub enum Value {
308    Empty,
309    Errata(Errata),
310    Literal(Literal),
311    Array(Vec<Box<Value>>),
312    Closure(Closure),
313    Assignment(Reference),
314    Format(Format),
315    Eval(Eval),
316    Node(Node),
317}
318
319impl Value {
320    /// Create a Value from a number.
321    ///
322    /// This is a convenience method for creating number values.
323    ///
324    /// # Arguments
325    ///
326    /// * `number` - The numeric value
327    ///
328    /// # Examples
329    ///
330    /// ```rust
331    /// use aimx::Value;
332    ///
333    /// let number_value = Value::from_number(42.0);
334    /// assert!(number_value.is_number());
335    /// ```
336    pub fn from_number(number: f64) -> Value {
337        Value::Literal(Literal::from_number(number))
338    }
339
340    /// Check if this value of the specified type definition.
341    ///
342    /// This method determines whether this value conforms to the specified type
343    /// definition. For arrays, it checks if the first element (if any) matches
344    /// the type. For literals, it checks if the literal matches the type.
345    ///
346    /// # Arguments
347    ///
348    /// * `typedef` - The type definition to check against
349    ///
350    /// # Returns
351    ///
352    /// Returns `true` if this value matches the specified type, `false` otherwise.
353    ///
354    /// # Examples
355    ///
356    /// ```rust
357    /// use aimx::{Value, Literal, Typedef};
358    ///
359    /// let number_value = Value::Literal(Literal::from_number(42.0));
360    /// assert!(number_value.is_of_type(&Typedef::Number));
361    ///
362    /// let text_value = Value::Literal(Literal::from_text("Hello".to_string()));
363    /// assert!(text_value.is_of_type(&Typedef::Text));
364    ///
365    /// let array_value = Value::Array(vec![
366    ///     Box::new(Value::Literal(Literal::from_number(1.0))),
367    ///     Box::new(Value::Literal(Literal::from_number(2.0))),
368    /// ]);
369    /// assert!(array_value.is_of_type(&Typedef::Number));
370    /// ```
371    pub fn is_of_type(&self, typedef: &Typedef) -> bool {
372        match self {
373            Value::Empty => true,
374            Value::Errata(_) => false,
375            Value::Literal(literal) => typedef.is_literal() && literal.is_type(typedef),
376            Value::Array(array) => {
377                if typedef.is_any_array() {
378                    true
379                }
380                else if array.len() > 0 {
381                    let literal_typedef = typedef.as_literal();
382                    array.last().unwrap().as_ref().is_of_type(&literal_typedef)
383                } else {
384                    false
385                }
386            }
387            Value::Closure(_) => typedef.is_closure(),
388            Value::Assignment(_) => true,
389            Value::Format(_) => typedef.is_format(),
390            Value::Eval(_) => typedef.is_eval(),
391            Value::Node(_) => typedef.is_node(),
392        }
393    }
394
395    /// Check if this value matches the actual type definition, considering nested arrays.
396    ///
397    /// This method provides a more precise type checking than `is_of_type` by properly
398    /// handling nested array structures and ensuring the actual type matches the definition.
399    ///
400    /// # Arguments
401    ///
402    /// * `typedef` - The type definition to check against
403    ///
404    /// # Returns
405    ///
406    /// Returns `true` if this value's actual type matches the specified type definition,
407    /// `false` otherwise.
408    pub fn is_actual_type(&self, typedef: &Typedef) -> bool {
409        match self {
410            Value::Empty => true,
411            Value::Errata(_) => false,
412            Value::Literal(literal) => typedef.is_literal() && literal.is_type(typedef),
413            Value::Array(array) => {
414                if typedef.is_any_array() {
415                    true
416                } else if typedef.is_literal() {
417                    false
418                } else if array.len() > 0 {
419                    let last = array.last().unwrap().as_ref();
420                    if last.is_array() {
421                         last.is_actual_type(typedef)
422                    } else {
423                        let literal_typedef = typedef.as_literal();
424                        last.is_actual_type(&literal_typedef)
425                    }
426                    
427                } else {
428                    false
429                }
430            }
431            Value::Closure(_) => typedef.is_closure(),
432            Value::Assignment(_) => false,
433            Value::Format(_) => typedef.is_format(),
434            Value::Eval(_) => typedef.is_eval(),
435            Value::Node(_) => typedef.is_node(),
436        }
437    }
438
439    /// Get the type of this value.
440    ///
441    /// # Returns
442    ///
443    /// Returns a `Result<Typedef>` containing the type of this value,
444    /// or an error if this is an Empty value.
445    pub fn get_type(&self) -> Result<Typedef> {
446        match self {
447            Value::Empty => Err(anyhow!("Expecting type, found Empty")),
448            Value::Errata(_) => Err(anyhow!("Expecting type, found Error")),
449            Value::Literal(literal) => literal.get_type(),
450            Value::Array(array) => {
451                if array.len() > 0 {
452                    let typedef = array.last().unwrap().as_ref().get_type()?;
453                    Ok(typedef.as_array())
454                } else {
455                    Ok(Typedef::Array)
456                }
457            }
458            Value::Closure(_) => Ok(Typedef::Closure),
459            Value::Assignment(_) => Ok(Typedef::Any),
460            Value::Format(_) => Ok(Typedef::Format),
461            Value::Eval(_) => Ok(Typedef::Eval),
462            Value::Node(_) => Ok(Typedef::Node),
463        }
464    }
465
466    /// Convert this value to match the type of another value.
467    ///
468    /// This method performs type conversion according to the AIMX grammar's
469    /// type promotion rules, converting this value to match the type
470    /// of the provided reference value.
471    ///
472    /// Type conversion follows these rules:
473    /// - If the reference value is a `Bool`, converts this value to boolean
474    /// - If the reference value is a `Date`, converts this value to date
475    /// - If the reference value is a `Number`, converts this value to number
476    /// - If the reference value is a `Task`, converts this value to task
477    /// - If the reference value is `Text`, converts this value to text
478    ///
479    /// # Arguments
480    ///
481    /// * `value` - The reference value whose type determines the conversion
482    ///
483    /// # Returns
484    ///
485    /// Returns a `Result<Value>` containing the converted value or an error
486    /// if conversion is not possible (e.g., trying to convert Empty to a specific type).
487    ///
488    /// # Examples
489    ///
490    /// ```rust
491    /// use aimx::{Value, Literal};
492    ///
493    /// let number_value = Value::Literal(Literal::from_number(42.0));
494    /// let text_reference = Value::Literal(Literal::from_text("example".to_string()));
495    ///
496    /// // Convert number to text
497    /// let converted = number_value.clone().as_type(&text_reference).unwrap();
498    /// assert!(converted.is_text());
499    ///
500    /// let bool_reference = Value::Literal(Literal::from_bool(true));
501    /// // Convert number to boolean
502    /// let converted = number_value.as_type(&bool_reference).unwrap();
503    /// assert!(converted.is_bool());
504    /// ```
505    pub fn as_type(self, value: &Value) -> Result<Value> {
506        let literal = value.to_literal();
507        match literal {
508            Literal::Empty => Err(anyhow!("Expecting type as {}, found Empty", literal.type_as_string())),
509            Literal::Bool(_) => Ok(self.as_bool()),
510            Literal::Date(_) => self.as_date(),
511            Literal::Number(_) => self.as_number(),
512            Literal::Task(..) => self.as_task(),
513            Literal::Text(_) => self.as_text(),
514        }
515    }
516
517    /// Convert this value to a specific type definition.
518    ///
519    /// This method performs type conversion according to the AIMX grammar's
520    /// type promotion rules, converting this value to match the specified
521    /// type definition.
522    ///
523    /// # Arguments
524    ///
525    /// * `typedef` - The type definition to convert to
526    ///
527    /// # Returns
528    ///
529    /// Returns a `Result<Value>` containing the converted value or an error
530    /// if conversion is not possible.
531    ///
532    /// # Type Conversion Rules
533    ///
534    /// The conversion follows these rules:
535    /// - **Any**: Returns the value unchanged
536    /// - **Array**: Converts non-arrays to single-element arrays
537    /// - **Literal types**: Converts values to the specified literal type
538    /// - **Array types**: Converts arrays to the specified element type
539    /// - **Closure**: Only allows conversion if already a closure
540    ///
541    /// # Examples
542    ///
543    /// ```rust
544    /// use aimx::{Value, Literal, Typedef};
545    ///
546    /// let number_value = Value::Literal(Literal::from_number(42.0));
547    /// 
548    /// // Convert to text
549    /// let text_value = number_value.clone().to_type(&Typedef::Text).unwrap();
550    /// assert!(text_value.is_text());
551    /// 
552    /// // Convert to array
553    /// let array_value = number_value.to_type(&Typedef::NumberArray).unwrap();
554    /// assert!(array_value.is_array());
555    /// ```
556    pub fn to_type(self, typedef: &Typedef) -> Result<Value> {
557        // Downgrade to array
558        if self.is_array() && typedef.is_literal() {
559            let literal = self.to_literal().clone().to_type(typedef)?;
560            Ok(Value::Literal(literal))
561        } else {
562            match typedef {
563                // Literally any value
564                Typedef::Any => Ok(self),
565                // Upgrade array
566                Typedef::Array => {
567                    if self.is_array() {
568                        Ok(self)
569                    } else {
570                        Ok(self.as_array())
571                    }
572                }
573                Typedef::Bool => {
574                    if self.is_literal() {
575                        Ok(self.as_bool())
576                    }
577                    else {
578                        Ok(self.as_literal().as_bool())
579                    }
580                }
581                Typedef::BoolArray => {
582                    if self.is_array() {
583                        Ok(self.as_bool())
584                    } else {
585                        Ok(self.as_bool().as_array())
586                    }
587                }
588                Typedef::Date => self.as_date(),
589                Typedef::DateArray => {
590                    if self.is_array() {
591                        self.as_date()
592                    } else {
593                        let value = self.as_date()?;
594                        Ok(value.as_array())
595                    }
596                }
597                Typedef::Number  => self.as_number(),
598                Typedef::NumberArray => {
599                    if self.is_array() {
600                        self.as_number()
601                    } else {
602                        let value = self.as_number()?;
603                        Ok(value.as_array())
604                    }
605                }
606                Typedef::Task => self.as_task(),
607                Typedef::TaskArray => {
608                    if self.is_array() {
609                        self.as_task()
610                    } else {
611                        let value = self.as_task()?;
612                        Ok(value.as_array())
613                    }
614                }
615                Typedef::Text => self.as_text(),
616                Typedef::TextArray => {
617                    if self.is_array() {
618                        self.as_text()
619                    } else {
620                        let value = self.as_text()?;
621                        Ok(value.as_array())
622                    }
623                }
624                Typedef::Closure => if self.is_closure() {
625                        Ok(self)
626                    } else {
627                        Err(anyhow!("Expecting Closure, found {}", self.type_as_string()))
628                    }
629                Typedef::Eval | Typedef::Format | Typedef::Node =>
630                    Err(anyhow!("Invalid type conversion from {} to {}", self.type_as_string(), typedef.as_string()))
631            }
632        }
633    }
634
635    /// Check if this value is empty.
636    ///
637    /// Returns `true` if this value is the `Empty` variant, `false` otherwise.
638    ///
639    /// # Examples
640    ///
641    /// ```rust
642    /// use aimx::Value;
643    ///
644    /// let empty_value = Value::Empty;
645    /// let non_empty_value = Value::Literal(aimx::Literal::from_number(42.0));
646    ///
647    /// assert!(empty_value.is_empty());
648    /// assert!(!non_empty_value.is_empty());
649    /// ```
650    pub fn is_empty(&self) -> bool {
651        match self {
652            Value::Empty | Value::Literal(Literal::Empty) => true,
653            _ => false,
654        }
655    }
656
657    /// Check if this value contains an error.
658    ///
659    /// Returns `true` if this value represents an error condition,
660    /// `false` otherwise.
661    pub fn has_error(&self) -> bool {
662        match self {
663            Value::Errata(_) => true,
664            _ => false,
665        }
666    }
667
668    /// Check if this value contains an error (alias for has_error).
669    ///
670    /// Returns `true` if this value represents an error condition,
671    /// `false` otherwise.
672    pub fn has_errata(&self) -> bool {
673        self.has_error()
674    }
675
676    /// Check if this value is a literal.
677    ///
678    /// Returns `true` if this value is the `Literal` variant, `false` otherwise.
679    /// This includes all scalar types: booleans, numbers, text, dates, and tasks.
680    ///
681    /// # Examples
682    ///
683    /// ```rust
684    /// use aimx::{Value, Literal};
685    ///
686    /// let literal_value = Value::Literal(Literal::from_number(42.0));
687    /// let array_value = Value::Array(vec![]);
688    /// let empty_value = Value::Empty;
689    ///
690    /// assert!(literal_value.is_literal());
691    /// assert!(!array_value.is_literal());
692    /// assert!(!empty_value.is_literal());
693    /// ```
694    pub fn is_literal(&self) -> bool {
695        match self {
696            Value::Literal(_) => true,
697            _ => false,
698        }
699    }
700
701
702    /// Check if this value is constant (immutable).
703    ///
704    /// Returns `true` if this value represents a constant value that
705    /// cannot be modified during evaluation, `false` otherwise.
706    pub fn is_constant(&self) -> bool {
707        match self {
708            Value::Literal(_)
709            | Value::Array(_) => true,
710            _ => false,
711        }
712    }
713
714    /// Get a reference to the literal representation of this value.
715    ///
716    /// Returns a reference to a [`Literal`] representing this value's type and content:
717    /// - For literal values, returns a reference to the embedded literal
718    /// - For arrays, returns the literal representation of the last element or `Literal::Empty` for empty arrays
719    /// - For all other value types, returns `Literal::Empty`
720    ///
721    /// This method is useful for type checking and introspection, as it provides
722    /// access to the underlying literal type without consuming the value.
723    ///
724    /// # Examples
725    ///
726    /// ```rust
727    /// use aimx::{Value, Literal};
728    ///
729    /// let literal_value = Value::Literal(Literal::from_number(42.0));
730    /// assert!(literal_value.to_literal().is_number());
731    ///
732    /// let array_value = Value::Array(vec![
733    ///     Box::new(Value::Literal(Literal::from_text("first".to_string()))),
734    ///     Box::new(Value::Literal(Literal::from_text("last".to_string()))),
735    /// ]);
736    /// assert!(array_value.to_literal().is_text());
737    ///
738    /// let empty_value = Value::Empty;
739    /// assert!(empty_value.to_literal().is_empty());
740    /// ```
741    pub fn to_literal(&self) -> &Literal {
742        match self {
743            Value::Literal(literal) => literal,
744            Value::Array(array) => {
745                if array.len() > 0 {
746                    array.last().unwrap().as_ref().to_literal()
747                } else {
748                    &Literal::Empty
749                }
750            }
751            _ => &Literal::Empty,
752        }
753    }
754
755    /// Convert this value to its literal representation.
756    ///
757    /// This method consumes the value and returns the underlying literal representation:
758    /// - For literal values, returns the literal itself
759    /// - For arrays, returns the last element or `Value::Empty` for empty arrays
760    /// - For all other value types, returns `Value::Empty`
761    ///
762    /// # Examples
763    ///
764    /// ```rust
765    /// use aimx::{Value, Literal};
766    ///
767    /// let literal_value = Value::Literal(Literal::from_number(42.0));
768    /// let literal = literal_value.as_literal();
769    /// assert!(literal.is_literal());
770    ///
771    /// let array_value = Value::Array(vec![
772    ///     Box::new(Value::Literal(Literal::from_text("first".to_string()))),
773    ///     Box::new(Value::Literal(Literal::from_text("last".to_string()))),
774    /// ]);
775    /// let literal = array_value.as_literal();
776    /// assert!(literal.is_literal());
777    ///
778    /// let empty_value = Value::Empty;
779    /// let literal = empty_value.as_literal();
780    /// assert!(literal.is_empty());
781    /// ```
782    pub fn as_literal(self) -> Value {
783        match self {
784            Value::Literal(_) => self,
785            Value::Array(mut array) => {
786                if &array.len() > &0 {
787                    match array.pop() {
788                        Some(value) => *value,
789                        None => Value::Empty,
790                    }
791                } else {
792                    Value::Empty
793                }
794            }
795            _ => Value::Empty,
796        }
797    }
798
799    /// Check if this value is an array.
800    ///
801    /// Returns `true` if this value is the `Array` variant, `false` otherwise.
802    ///
803    /// # Examples
804    ///
805    /// ```
806    /// use aimx::{Value, Literal};
807    ///
808    /// let array_value = Value::Array(vec![]);
809    /// let literal_value = Value::Literal(Literal::from_number(42.0));
810    /// let empty_value = Value::Empty;
811    ///
812    /// assert!(array_value.is_array());
813    /// assert!(!literal_value.is_array());
814    /// assert!(!empty_value.is_array());
815    /// ```
816    pub fn is_array(&self) -> bool {
817        match self {
818            Value::Array(_) => true,
819            _ => false,
820        }
821    }
822
823
824    /// Convert this value to an array representation.
825    ///
826    /// If the value is already an array or empty, returns it unchanged.
827    /// If the value is a literal, wraps it in a single-element array.
828    /// Otherwise, returns an empty value.
829    pub fn as_array(self) -> Value {
830        // Early return if no conversion is needed
831        if self.is_empty() || self.is_array() {
832            self
833        } else if self.is_literal() {
834            let mut array: Vec<Box<Value>> = Vec::new();
835            array.push(Box::new(self));
836            Value::Array(array)
837        } else {
838            Value::Empty
839        }
840    }
841
842    /// Check if this value represents a boolean.
843    ///
844    /// Returns `true` if this value is a literal boolean, `false` otherwise.
845    ///
846    /// # Examples
847    ///
848    /// See [`Value::as_bool`] for examples of boolean conversion behavior.
849    pub fn is_bool(&self) -> bool {
850        match self {
851            Value::Literal(Literal::Bool(_)) => true,
852            _ => false,
853        }
854    }
855
856    /// Convert this value to a boolean representation.
857    ///
858    /// Performs type conversion to boolean according to the AIMX grammar's
859    /// truthiness rules:
860    /// - Empty values: Always false
861    /// - Numbers: 0 is false, non-zero is true
862    /// - Text: Empty string is false, non-empty is true
863    /// - Dates: Always true (they exist)
864    /// - Arrays: Empty array is false, non-empty is true
865    /// - Tasks: Status determines value, no status is false
866    ///
867    /// # Examples
868    ///
869    /// ```
870    /// use aimx::{Value, Literal};
871    ///
872    /// let number_zero = Value::Literal(Literal::from_number(0.0));
873    /// let as_bool = number_zero.as_bool();
874    /// // Zero converts to false
875    /// assert!(!as_bool.to_literal().to_bool());
876    ///
877    /// let number_non_zero = Value::Literal(Literal::from_number(42.0));
878    /// let as_bool = number_non_zero.as_bool();
879    /// // Non-zero converts to true
880    /// assert!(as_bool.to_literal().to_bool());
881    ///
882    /// let empty_text = Value::Literal(Literal::from_text("".to_string()));
883    /// let as_bool = empty_text.as_bool();
884    /// // Empty string converts to false
885    /// assert!(!as_bool.to_literal().to_bool());
886    /// ```
887    pub fn as_bool(self) -> Value {
888        // Early return if no conversion is needed
889        match &self {
890            Value::Empty => return self,
891            Value::Literal(literal) if literal.is_bool() => return self,
892            _ => {}
893        }
894        // Now do the conversion for cases that need it
895        match self {
896            Value::Literal(literal) => Value::Literal(literal.as_bool()),
897            Value::Array(array) => {
898                let bool_array: Vec<Box<Value>> = array
899                    .into_iter()
900                    .map(|box_value| {
901                        let value: Value = *box_value; 
902                        if value.is_bool() {
903                            Box::new(value)
904                        } else {
905                            let value = value.as_bool();
906                            Box::new(value)
907                        }
908                    })
909                    .collect();
910                Value::Array(bool_array)
911            }
912            _ => Value::Empty,
913        }
914    }
915
916    /// Check if this value represents a date.
917    ///
918    /// Returns `true` if this value is a literal date, `false` otherwise.
919    ///
920    /// # Examples
921    ///
922    /// ```
923    /// use aimx::{Value, Literal};
924    ///
925    /// let date_value = Value::Literal(Literal::Date(jiff::civil::DateTime::new(2023, 1, 1, 0, 0, 0, 0).unwrap()));
926    /// let number_value = Value::Literal(Literal::from_number(42.0));
927    ///
928    /// assert!(date_value.is_date());
929    /// assert!(!number_value.is_date());
930    /// ```
931    pub fn is_date(&self) -> bool {
932        match self {
933            Value::Literal(Literal::Date(_)) => true,
934            _ => false,
935        }
936    }
937
938    /// Convert this value to a date representation.
939    ///
940    /// Attempts to convert the value to a date according to the AIMX grammar's
941    /// conversion rules:
942    /// - Empty values: Remain empty (no conversion needed)
943    /// - Dates: No conversion needed
944    /// - Text: Parsed as date if possible (e.g., "2023-01-01")
945    /// - Number: Interpreted as Unix timestamp
946    /// - Boolean: true becomes Unix epoch + 1 second, false becomes Unix epoch
947    /// - Task: Text component parsed as date if possible
948    ///
949    /// # Returns
950    ///
951    /// Returns a `Result<Value>` containing the converted date value or an error
952    /// if conversion is not possible.
953    ///
954    /// # Examples
955    ///
956    /// ```
957    /// use aimx::{Value, Literal};
958    ///
959    /// let text_date = Value::Literal(Literal::from_text("2023-01-01".to_string()));
960    /// let as_date = text_date.as_date().unwrap();
961    /// assert!(as_date.is_date());
962    ///
963    /// let number_timestamp = Value::Literal(Literal::from_number(1672531200.0)); // 2023-01-01 UTC
964    /// let as_date = number_timestamp.as_date().unwrap();
965    /// assert!(as_date.is_date());
966    /// ```
967    pub fn as_date(self) -> Result<Value> {
968        // Early return if no conversion is needed
969        match &self {
970            Value::Empty => return Ok(self),
971            Value::Literal(literal) if literal.is_date() => return Ok(self),
972            _ => {}
973        }
974        // Now do the conversion for cases that need it
975        Ok(match self {
976            Value::Literal(literal) => Value::Literal(literal.as_date()?),
977            Value::Array(array) => {
978                let date_array: Result<Vec<Box<Value>>, anyhow::Error> = array
979                    .into_iter()
980                    .map(|box_value| {
981                        let value: Value = *box_value; 
982                        if value.is_date() {
983                            Ok(Box::new(value))
984                        } else {
985                            let converted_value = value.as_date()?;
986                            Ok(Box::new(converted_value))
987                        }
988                    })
989                    .collect();
990                Value::Array(date_array?)
991            }
992            _ => return Err(anyhow!("Cannot convert {} to Date", self.type_as_string())),
993        })
994    }
995
996    /// Check if this value represents a number.
997    ///
998    /// Returns `true` if this value is a literal number, `false` otherwise.
999    ///
1000    /// # Examples
1001    ///
1002    /// ```rust
1003    /// use aimx::{Value, Literal};
1004    ///
1005    /// let number_value = Value::Literal(Literal::from_number(42.0));
1006    /// let text_value = Value::Literal(Literal::from_text("hello".to_string()));
1007    ///
1008    /// assert!(number_value.is_number());
1009    /// assert!(!text_value.is_number());
1010    /// ```
1011    pub fn is_number(&self) -> bool {
1012        match self {
1013            Value::Literal(Literal::Number(_)) => true,
1014            _ => false,
1015        }
1016    }
1017
1018    /// Convert this value to a number representation.
1019    ///
1020    /// Attempts to convert the value to a number according to the AIMX grammar's
1021    /// conversion rules:
1022    /// - Empty values: Remain empty (no conversion needed)
1023    /// - Numbers: No conversion needed
1024    /// - Text: Parsed as number if it represents a valid numeric literal (e.g., "42", "3.14")
1025    /// - Boolean: false becomes 0, true becomes 1
1026    /// - Date: Converted to Unix timestamp
1027    /// - Task: Status determines value (true=1, false=-1, none=0)
1028    ///
1029    /// # Returns
1030    ///
1031    /// Returns a `Result<Value>` containing the converted number value or an error
1032    /// if conversion is not possible.
1033    ///
1034    /// # Examples
1035    ///
1036    /// ```
1037    /// use aimx::{Value, Literal};
1038    ///
1039    /// let text_number = Value::Literal(Literal::from_text("42".to_string()));
1040    /// let as_number = text_number.as_number().unwrap();
1041    /// assert!(as_number.is_number());
1042    ///
1043    /// let bool_true = Value::Literal(Literal::from_bool(true));
1044    /// let as_number = bool_true.as_number().unwrap();
1045    /// // true converts to 1
1046    /// assert_eq!(as_number.to_literal().to_number().unwrap(), 1.0);
1047    /// ```
1048    pub fn as_number(self) -> Result<Value> {
1049        // Early return if no conversion is needed
1050        match &self {
1051            Value::Empty => return Ok(self),
1052            Value::Literal(literal) if literal.is_number() => return Ok(self),
1053            _ => {}
1054        }
1055        // Now do the conversion for cases that need it
1056        Ok(match self {
1057            Value::Literal(literal) => Value::Literal(literal.as_number()?),
1058            Value::Array(array) => {
1059                let number_array: Result<Vec<Box<Value>>, anyhow::Error> = array
1060                    .into_iter()
1061                    .map(|box_value| {
1062                        let value: Value = *box_value; 
1063                        if value.is_number() {
1064                            Ok(Box::new(value))
1065                        } else {
1066                            let converted_value = value.as_number()?;
1067                            Ok(Box::new(converted_value))
1068                        }
1069                    })
1070                    .collect();
1071                Value::Array(number_array?)
1072            }
1073            _ => return Err(anyhow!("Cannot convert {} to Number", self.type_as_string())),
1074        })
1075    }
1076
1077    /// Extract a numeric value from this value.
1078    ///
1079    /// This is a convenience method for when you specifically need a `f64` number.
1080    /// It's particularly useful for arithmetic operations and mathematical functions.
1081    ///
1082    /// # Returns
1083    ///
1084    /// Returns a `Result<f64>` containing the numeric value or an error if:
1085    /// - The value is empty
1086    /// - The value is an array with no elements
1087    /// - The underlying literal cannot be converted to a number
1088    ///
1089    /// # Examples
1090    ///
1091    /// ```
1092    /// use aimx::{Value, Literal};
1093    ///
1094    /// let number_value = Value::Literal(Literal::from_number(42.5));
1095    /// let num = number_value.to_number().unwrap();
1096    /// assert_eq!(num, 42.5);
1097    ///
1098    /// let array_value = Value::Array(vec![
1099    ///     Box::new(Value::Literal(Literal::from_number(10.0))),
1100    ///     Box::new(Value::Literal(Literal::from_number(20.0))),
1101    /// ]);
1102    /// let num = array_value.to_number().unwrap();
1103    /// // For arrays, gets the last element's number
1104    /// assert_eq!(num, 20.0);
1105    /// ```
1106    pub fn to_number(&self) -> Result<f64> {
1107        match self {
1108            Value::Literal(literal) => literal.to_number(),
1109            Value::Array(array) => {
1110                if array.len() > 0 {
1111                    array.last().unwrap().as_ref().to_number()
1112                } else {
1113                    Err(anyhow!("Cannot convert empty Array to Number"))
1114                }
1115            }
1116            _ => Err(anyhow!("Cannot convert {} to Number", self.type_as_string())),
1117        }
1118    }
1119
1120    /// Check if this value represents a task.
1121    ///
1122    /// Returns `true` if this value is a literal task, `false` otherwise.
1123    ///
1124    /// # Examples
1125    ///
1126    /// ```
1127    /// use aimx::{Value, Literal};
1128    ///
1129    /// let task_value = Value::Literal(Literal::from_task(Some(true), "Completed task".to_string()));
1130    /// let text_value = Value::Literal(Literal::from_text("Just text".to_string()));
1131    ///
1132    /// assert!(task_value.is_task());
1133    /// assert!(!text_value.is_task());
1134    /// ```
1135    pub fn is_task(&self) -> bool {
1136        match self {
1137            Value::Literal(Literal::Task(..)) => true,
1138            _ => false,
1139        }
1140    }
1141
1142    /// Convert this value to a task representation.
1143    ///
1144    /// Attempts to convert the value to a task according to the AIMX grammar's
1145    /// conversion rules:
1146    /// - Empty values: Remain empty (no conversion needed)
1147    /// - Tasks: No conversion needed
1148    /// - Boolean: Status becomes the boolean value, text becomes "true"/"false"
1149    /// - Date: No status, text becomes date string
1150    /// - Number: Status based on sign (positive=true, negative=false, zero=none), text becomes number string
1151    /// - Text: No status, text remains the same
1152    ///
1153    /// # Returns
1154    ///
1155    /// Returns a `Result<Value>` containing the converted task value or an error
1156    /// if conversion is not possible.
1157    ///
1158    /// # Examples
1159    ///
1160    /// ```
1161    /// use aimx::{Value, Literal};
1162    ///
1163    /// let bool_true = Value::Literal(Literal::from_bool(true));
1164    /// let as_task = bool_true.as_task().unwrap();
1165    /// assert!(as_task.is_task());
1166    ///
1167    /// let text_value = Value::Literal(Literal::from_text("Pending task".to_string()));
1168    /// let as_task = text_value.as_task().unwrap();
1169    /// // Text converts to task with no status
1170    /// assert_eq!(as_task.to_literal().to_string(), "[ ] Pending task");
1171    /// ```
1172    pub fn as_task(self) -> Result<Value> {
1173        // Early return if no conversion is needed
1174        match &self {
1175            Value::Empty => return Ok(self),
1176            Value::Literal(literal) if literal.is_task() => return Ok(self),
1177            _ => {}
1178        }
1179        // Now do the conversion for cases that need it
1180        Ok(match self {
1181            Value::Literal(literal) => Value::Literal(literal.as_task()?),
1182            Value::Array(array) => {
1183                let task_array: Result<Vec<Box<Value>>, anyhow::Error> = array
1184                    .into_iter()
1185                    .map(|box_value| {
1186                        let value: Value = *box_value; 
1187                        if value.is_task() {
1188                            Ok(Box::new(value))
1189                        } else {
1190                            let converted_value = value.as_task()?;
1191                            Ok(Box::new(converted_value))
1192                        }
1193                    })
1194                    .collect();
1195                Value::Array(task_array?)
1196            }
1197            _ => return Err(anyhow!("Cannot convert {} to Task", self.type_as_string())),
1198        })
1199    }
1200
1201    /// Check if this value represents text.
1202    ///
1203    /// Returns `true` if this value is a literal text, `false` otherwise.
1204    ///
1205    /// # Examples
1206    ///
1207    /// ```
1208    /// use aimx::{Value, Literal};
1209    ///
1210    /// let text_value = Value::Literal(Literal::from_text("Hello".to_string()));
1211    /// let number_value = Value::Literal(Literal::from_number(42.0));
1212    ///
1213    /// assert!(text_value.is_text());
1214    /// assert!(!number_value.is_text());
1215    /// ```
1216    pub fn is_text(&self) -> bool {
1217        match self {
1218            Value::Literal(Literal::Text(_)) => true,
1219            _ => false,
1220        }
1221    }
1222
1223    /// Convert this value to a text representation.
1224    ///
1225    /// Converts the value to text according to the AIMX grammar's conversion rules:
1226    /// - Empty values: Remain empty (no conversion needed)
1227    /// - Text: No conversion needed
1228    /// - Boolean: "true" or "false"
1229    /// - Date: Formatted as ISO 8601 date string (e.g., "2023-01-01T00:00:00.000")
1230    /// - Number: Formatted as string (e.g., "42", "3.14")
1231    /// - Task: Text component of the task (status is preserved in the Value but not in the text conversion)
1232    ///
1233    /// # Returns
1234    ///
1235    /// Returns a `Result<Value>` containing the converted text value or an error
1236    /// if conversion is not possible.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```rust
1241    /// use aimx::{Value, Literal};
1242    ///
1243    /// let number_value = Value::Literal(Literal::from_number(42.0));
1244    /// let as_text = number_value.as_text().unwrap();
1245    /// assert!(as_text.is_text());
1246    /// assert_eq!(as_text.to_literal().to_string(), "42");
1247    ///
1248    /// let bool_true = Value::Literal(Literal::from_bool(true));
1249    /// let as_text = bool_true.as_text().unwrap();
1250    /// assert_eq!(as_text.to_literal().to_string(), "true");
1251    /// ```
1252    pub fn as_text(self) -> Result<Value> {
1253        // Early return if no conversion is needed
1254        match &self {
1255            Value::Empty => return Ok(self),
1256            Value::Literal(literal) if literal.is_text() => return Ok(self),
1257            _ => {}
1258        }
1259        // Now do the conversion for cases that need it
1260        Ok(match self {
1261            Value::Literal(literal) => Value::Literal(literal.as_text()?),
1262            Value::Array(array) => {
1263                let text_array: Result<Vec<Box<Value>>, anyhow::Error> = array
1264                    .into_iter()
1265                    .map(|box_value| {
1266                        let value: Value = *box_value; 
1267                        if value.is_text() {
1268                            Ok(Box::new(value))
1269                        } else {
1270                            let converted_value = value.as_text()?;
1271                            Ok(Box::new(converted_value))
1272                        }
1273                    })
1274                    .collect();
1275                Value::Array(text_array?)
1276            }
1277            _ => return Err(anyhow!("Cannot convert {} to Text", self.type_as_string())),
1278        })
1279    }
1280
1281    /// Check if this value represents a closure.
1282    ///
1283    /// Returns `true` if this value is a closure, `false` otherwise.
1284    pub fn is_closure(&self) -> bool {
1285        match self {
1286            Value::Closure(_) => true,
1287            _ => false,
1288        }
1289    }
1290
1291    /// Invoke this value as a closure.
1292    ///
1293    /// If this value is a closure, invokes it with the given context.
1294    /// Otherwise, returns an error.
1295    ///
1296    /// # Arguments
1297    ///
1298    /// * `context` - The evaluation context to use for invocation
1299    ///
1300    /// # Returns
1301    ///
1302    /// Returns a `Result<Value>` containing the result of closure invocation
1303    /// or an error if this value is not a closure.
1304    pub fn invoke(&self, context: &mut dyn ContextLike) -> Result<Value> {
1305        match self {
1306            Value::Closure(closure) => closure.invoke(context),
1307            _ => Err(anyhow!("Expecting Closure, found {}", self.type_as_string()))
1308        }
1309    }
1310
1311    /// Check if this value represents a format.
1312    ///
1313    /// Returns `true` if this value is a format, `false` otherwise.
1314    pub fn is_format(&self) -> bool {
1315        match self {
1316            Value::Format(_) => true,
1317            _ => false,
1318        }
1319    }
1320
1321    /// Check if this value represents an eval.
1322    ///
1323    /// Returns `true` if this value is an eval, `false` otherwise.
1324    pub fn is_eval(&self) -> bool {
1325        match self {
1326            Value::Eval(_) => true,
1327            _ => false,
1328        }
1329    }
1330
1331    /// Check if this value represents a node.
1332    ///
1333    /// Returns `true` if this value is a node, `false` otherwise.
1334    pub fn is_node(&self) -> bool {
1335        match self {
1336            Value::Node(_) => true,
1337            _ => false,
1338        }
1339    }
1340
1341    /// Get a string representation of this value's type. Used to provide type information
1342    /// in error messages.
1343    ///
1344    /// Returns a string indicating the type of this value based on its underlying literal
1345    /// representation. Possible return values are: "Empty", "Error", "Bool", "Date", "Number",
1346    /// "Task", "Text", "Closure", "Node".
1347    ///
1348    /// # Examples
1349    ///
1350    /// ```rust
1351    /// use aimx::{Value, Literal};
1352    ///
1353    /// let number_value = Value::Literal(Literal::from_number(42.0));
1354    /// assert_eq!(number_value.type_as_string(), "Number");
1355    ///
1356    /// let text_value = Value::Literal(Literal::from_text("Hello".to_string()));
1357    /// assert_eq!(text_value.type_as_string(), "Text");
1358    ///
1359    /// let array_value = Value::Array(vec![
1360    ///     Box::new(Value::Literal(Literal::from_number(1.0))),
1361    /// ]);
1362    /// // For arrays, gets the type of the last element
1363    /// assert_eq!(array_value.type_as_string(), "Number");
1364    /// ```
1365    pub fn type_as_string(&self) -> &'static str {
1366        match self {
1367            Value::Empty => "Empty",
1368            Value::Errata(_) => "Error",
1369            Value::Literal(literal) => literal.type_as_string(),
1370            Value::Array(array) => {
1371                if array.len() > 0 {
1372                    array.last().unwrap().as_ref().type_as_string()
1373                } else {
1374                    "Empty"
1375                }
1376            }
1377            Value::Closure(_) => "Closure",
1378            Value::Assignment(_) => "Assignment",
1379            Value::Format(_) => "Format",
1380            Value::Eval(_) => "Eval",
1381            Value::Node(_) => "Node",
1382        }
1383    }
1384
1385    /// Convert value to string with specified prefix, for pretty printing.
1386    ///
1387    /// This method formats the value for display with the specified prefix style.
1388    /// It's primarily used for generating human-readable output with appropriate
1389    /// indentation and formatting.
1390    ///
1391    /// # Arguments
1392    ///
1393    /// * `prefix` - The prefix style to use for formatting (None, Unordered, Ordered)
1394    ///
1395    /// # Returns
1396    ///
1397    /// Returns a formatted string representation of the value.
1398    ///
1399    /// # Examples
1400    ///
1401    /// ```
1402    /// use aimx::{Value, Literal, writer::Prefix};
1403    ///
1404    /// let array_value = Value::Array(vec![
1405    ///     Box::new(Value::Literal(Literal::from_text("first".to_string()))),
1406    ///     Box::new(Value::Literal(Literal::from_text("second".to_string()))),
1407    /// ]);
1408    ///
1409    /// let formatted = array_value.to_pretty(Prefix::Unordered);
1410    /// // Would produce formatted output with bullet points
1411    /// ```
1412    pub fn to_pretty(&self, prefix: Prefix) -> String {
1413        let mut writer = Writer::new(PrintMode::None, prefix);
1414        writer.print_value(&prefix, self);
1415        writer.finish()
1416    }
1417
1418    // Helper function to get type order for consistent sorting
1419    fn type_order(&self) -> u8 {
1420        match self {
1421            Value::Empty => 0,
1422            Value::Errata(_) => 1,
1423            Value::Node(_) => 2,
1424            Value::Eval(_) => 3,
1425            Value::Format(_) => 4,
1426            Value::Assignment(_) => 5,
1427            Value::Closure(_) => 6,
1428            Value::Literal(_) => 7,
1429            Value::Array(_) => 8,
1430        }
1431    }
1432}
1433
1434impl PartialOrd for Value {
1435    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1436        // Define a consistent ordering by type first, then value
1437        // Type ordering: Empty < Bool < Number < Date < Task < Text
1438        let self_type_order = self.type_order();
1439        let other_type_order = other.type_order();
1440        if self_type_order > other_type_order {
1441            Some(Ordering::Greater)
1442        } else if self_type_order < other_type_order {
1443            Some(Ordering::Less)
1444        } else {
1445            match (self, other) {
1446                // Start by assuming the types match
1447                (Value::Empty, Value::Empty) => Some(Ordering::Equal),
1448                (Value::Literal(a), Value::Literal(b)) => a.partial_cmp(b),
1449                (Value::Array(a), Value::Array(b)) => {
1450                    // Compare arrays element by element
1451                    let len_a = a.len();
1452                    let len_b = b.len();
1453                    let min_len = std::cmp::min(len_a, len_b);
1454                    
1455                    for i in 0..min_len {
1456                        match a[i].partial_cmp(&b[i]) {
1457                            Some(Ordering::Equal) => continue,
1458                            other => return other,
1459                        }
1460                    }
1461                    
1462                    // If all compared elements are equal, compare by length
1463                    len_a.partial_cmp(&len_b)
1464                }
1465                _ => Some(Ordering::Equal),
1466            }
1467        }
1468    }
1469}
1470
1471impl Eq for Value {}
1472
1473impl Ord for Value {
1474    fn cmp(&self, other: &Self) -> Ordering {
1475        self.partial_cmp(other).unwrap()
1476    }
1477}
1478
1479/// Parse a comma-separated array element.
1480///
1481/// This helper function parses a single element in a comma-separated list,
1482/// handling both literal values and nested arrays. It expects to find a comma
1483/// followed by optional whitespace, then either a literal value or another array.
1484///
1485/// This function is used internally by the array parsing logic to handle
1486/// the elements after the first one in a comma-separated list.
1487///
1488/// # Arguments
1489///
1490/// * `input` - The input string to parse
1491///
1492/// # Returns
1493///
1494/// Returns an `IResult` containing the remaining input and the parsed value.
1495fn parse_comma(input: &str) -> IResult<&str, Value> {
1496    let (input, _) = multispace0.parse(input)?;
1497    let (input, _) = char(',').parse(input)?;
1498    let (input, _) = multispace0.parse(input)?;
1499    let (input, value) = if input.starts_with('(') {
1500        parse_value_array(input)
1501    } else {
1502        let (remain, literal) = parse_literal(input)?;
1503        Ok((remain, Value::Literal(literal)))
1504    }?;
1505    Ok((input, value))
1506}
1507
1508/// Parse a parenthesis-enclosed value array.
1509///
1510/// This function parses arrays that are enclosed in parentheses, such as `(1, 2, 3)`.
1511/// It handles both empty arrays `()` and arrays with values. For singleton literals
1512/// inside parentheses, it creates a single-element array.
1513///
1514/// # Arguments
1515///
1516/// * `input` - The input string to parse
1517///
1518/// # Returns
1519///
1520/// Returns an `IResult` containing the remaining input and the parsed array value.
1521fn parse_value_array(input: &str) -> IResult<&str, Value> {
1522  let (input, value) = delimited(
1523    char('('),
1524    parse_value,
1525    char(')'),
1526  ).parse(input)?;
1527  let value = match value {
1528    Value::Empty => Value::Array(Vec::new()),
1529    Value::Literal(_) => Value::Array(vec![Box::new(value)]),
1530    _ => value,
1531  };
1532  Ok((input, value))
1533}
1534
1535/// Parse a value from input text.
1536///
1537/// This is the main entry point for parsing values in the AIMX expression language.
1538/// It can parse three types of values:
1539/// 1. Empty values (whitespace-only input)
1540/// 2. Literal values (numbers, booleans, text, dates, tasks)
1541/// 3. Arrays (parenthesis-enclosed comma-separated lists)
1542///
1543/// The parser handles whitespace automatically and can parse nested arrays.
1544///
1545/// # Arguments
1546///
1547/// * `input` - The input string to parse
1548///
1549/// # Returns
1550///
1551/// Returns an `IResult` containing the remaining input and the parsed value.
1552///
1553/// # Examples
1554///
1555/// ```rust
1556/// use aimx::value::parse_value;
1557///
1558/// // Parse a number
1559/// let result = parse_value("42");
1560/// assert!(result.is_ok());
1561///
1562/// // Parse an array
1563/// let result = parse_value("(1, 2, 3)");
1564/// assert!(result.is_ok());
1565///
1566/// // Parse nested arrays
1567/// let result = parse_value("((1, 2), (3, 4))");
1568/// assert!(result.is_ok());
1569/// ```
1570pub fn parse_value(input: &str) -> IResult<&str, Value> {
1571    let input = input.trim();
1572    // Value is empty
1573    if input.is_empty() {
1574        return Ok((input, Value::Empty));
1575    }
1576    // Parenthesis enclosed array
1577    let (input, first) = if input.starts_with('(') {
1578        parse_value_array(input)
1579    } else {
1580        match parse_literal(input) {
1581            Ok((remain, literal)) => Ok((remain, Value::Literal(literal))),
1582            _ => Ok((input, Value::Empty)),
1583        }
1584    }?;
1585    if let Ok((input, value_list)) = many1(parse_comma).parse(input) {
1586        let mut array = vec![Box::new(first)];
1587        for conditional in value_list {
1588            array.push(Box::new(conditional));
1589        }
1590        let (input, _) = multispace0(input)?;
1591        Ok((input, Value::Array(array)))
1592    } else {
1593        let (input, _) = multispace0(input)?;
1594        Ok((input, first))
1595    }
1596}
1597
1598impl ExpressionLike for Value {
1599    fn evaluate(&self, _context: &mut dyn ContextLike) -> Result<Value> {
1600        Ok(self.clone())
1601    }
1602
1603    /// Write this value to the provided writer using the appropriate formatting.
1604    ///
1605    /// This implementation delegates to the writer's `print_value` method,
1606    /// which handles the formatting based on the writer's mode (string, sanitized, formula).
1607    ///
1608    /// # Arguments
1609    ///
1610    /// * `writer` - The writer to write to
1611    fn write(&self, writer: &mut Writer) {
1612        let prefix = writer.prefix();
1613        writer.print_value(&prefix, self);
1614    }
1615    
1616    /// Convert this value to a sanitized string representation.
1617    ///
1618    /// This method produces a string with special characters escaped
1619    /// to make it safe for various contexts. Useful for generating
1620    /// JSON-compatible or safely quoted output.
1621    ///
1622    /// # Returns
1623    ///
1624    /// A sanitized string representation of this value.
1625    fn to_sanitized(&self) -> String {
1626        let mut writer = Writer::sanitizer();
1627        let prefix = writer.prefix();
1628        writer.print_value(&prefix, self);
1629        writer.finish()
1630    }
1631    
1632    /// Convert this value to a formula string representation.
1633    ///
1634    /// This method produces a string with proper quoting and escaping
1635    /// for use in formulas. Useful for generating round-trippable
1636    /// representations that can be parsed back into values.
1637    ///
1638    /// # Returns
1639    ///
1640    /// A formula string representation of this value.
1641    fn to_formula(&self) -> String {
1642        let mut writer = Writer::formulizer();
1643        let prefix = writer.prefix();
1644        writer.print_value(&prefix, self);
1645        writer.finish()
1646    }
1647}
1648
1649impl fmt::Display for Value {
1650    /// Format this value for display using the default string representation.
1651    ///
1652    /// This implementation uses the stringizer writer mode to produce a
1653    /// human-readable representation of the value. For arrays, this will
1654    /// include proper formatting with newlines and indentation where appropriate.
1655    ///
1656    /// # Arguments
1657    ///
1658    /// * `f` - The formatter to write to
1659    ///
1660    /// # Returns
1661    ///
1662    /// A `fmt::Result` indicating success or failure of the formatting operation.
1663    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1664        let mut writer = Writer::stringizer();
1665        let prefix = writer.prefix();
1666        writer.print_value(&prefix, self);
1667        write!(f, "{}", writer.finish())
1668    }
1669}