kotoba_jsonnet/
ast.rs

1//! Abstract Syntax Tree for Jsonnet
2
3use crate::value::JsonnetValue;
4
5/// Part of a string interpolation
6#[derive(Debug, Clone, PartialEq)]
7pub enum StringInterpolationPart {
8    /// Literal string part
9    Literal(String),
10    /// Interpolated expression
11    Interpolation(Box<Expr>),
12}
13
14/// Expression node in the AST
15#[derive(Debug, Clone, PartialEq)]
16pub enum Expr {
17    /// Literal value (null, boolean, number, string)
18    Literal(JsonnetValue),
19
20    /// String with interpolation
21    StringInterpolation(Vec<StringInterpolationPart>),
22
23    /// Variable reference
24    Var(String),
25
26    /// Binary operation
27    BinaryOp {
28        left: Box<Expr>,
29        op: BinaryOp,
30        right: Box<Expr>,
31    },
32
33    /// Unary operation
34    UnaryOp {
35        op: UnaryOp,
36        expr: Box<Expr>,
37    },
38
39    /// Array literal
40    Array(Vec<Expr>),
41
42    /// Object literal
43    Object(Vec<ObjectField>),
44
45    /// Array comprehension
46    ArrayComp {
47        expr: Box<Expr>,
48        var: String,
49        array: Box<Expr>,
50        cond: Option<Box<Expr>>,
51    },
52
53    /// Object comprehension
54    ObjectComp {
55        field: Box<ObjectField>,
56        var: String,
57        array: Box<Expr>,
58    },
59
60    /// Function call
61    Call {
62        func: Box<Expr>,
63        args: Vec<Expr>,
64    },
65
66    /// Index access (array[index] or object.field)
67    Index {
68        target: Box<Expr>,
69        index: Box<Expr>,
70    },
71
72    /// Slice access (array[start:end:step])
73    Slice {
74        target: Box<Expr>,
75        start: Option<Box<Expr>>,
76        end: Option<Box<Expr>>,
77        step: Option<Box<Expr>>,
78    },
79
80    /// Local variable binding
81    Local {
82        bindings: Vec<(String, Expr)>,
83        body: Box<Expr>,
84    },
85
86    /// Function definition
87    Function {
88        parameters: Vec<String>,
89        body: Box<Expr>,
90    },
91
92    /// If-then-else expression
93    If {
94        cond: Box<Expr>,
95        then_branch: Box<Expr>,
96        else_branch: Option<Box<Expr>>,
97    },
98
99    /// Assert expression
100    Assert {
101        cond: Box<Expr>,
102        message: Option<Box<Expr>>,
103        expr: Box<Expr>,
104    },
105
106    /// Import expression
107    Import(String),
108
109    /// ImportStr expression
110    ImportStr(String),
111
112    /// Error expression
113    Error(Box<Expr>),
114}
115
116/// Object field definition
117#[derive(Debug, Clone, PartialEq)]
118pub struct ObjectField {
119    /// Field name (can be an expression for computed fields)
120    pub name: FieldName,
121    /// Field visibility
122    pub visibility: Visibility,
123    /// Field value expression
124    pub expr: Box<Expr>,
125}
126
127/// Field name variants
128#[derive(Debug, Clone, PartialEq)]
129pub enum FieldName {
130    /// Fixed string name
131    Fixed(String),
132    /// Computed name (expression)
133    Computed(Box<Expr>),
134}
135
136/// Field visibility
137#[derive(Debug, Clone, PartialEq)]
138pub enum Visibility {
139    /// Normal field (visible)
140    Normal,
141    /// Hidden field (not visible in output)
142    Hidden,
143    /// Forced field (always included even if null)
144    Forced,
145}
146
147/// Binary operators
148#[derive(Debug, Clone, PartialEq, Copy)]
149pub enum BinaryOp {
150    // Arithmetic
151    Add,
152    Sub,
153    Mul,
154    Div,
155    Mod,
156
157    // Comparison
158    Eq,
159    Ne,
160    Lt,
161    Le,
162    Gt,
163    Ge,
164
165    // Logical
166    And,
167    Or,
168
169    // Bitwise
170    BitAnd,
171    BitOr,
172    BitXor,
173    ShiftL,
174    ShiftR,
175
176    // Object operations
177    In,
178
179    // String concatenation
180    Concat,
181}
182
183/// Unary operators
184#[derive(Debug, Clone, PartialEq, Copy)]
185pub enum UnaryOp {
186    /// Logical NOT
187    Not,
188    /// Bitwise NOT
189    BitNot,
190    /// Unary minus
191    Neg,
192    /// Unary plus
193    Pos,
194}
195
196/// Statement (for top-level constructs)
197#[derive(Debug, Clone, PartialEq)]
198pub enum Stmt {
199    /// Expression statement
200    Expr(Expr),
201    /// Local binding at top level
202    Local(Vec<(String, Expr)>),
203    /// Assert at top level
204    Assert {
205        cond: Expr,
206        message: Option<Expr>,
207    },
208}
209
210/// Complete Jsonnet program (AST root)
211#[derive(Debug, Clone, PartialEq)]
212pub struct Program {
213    pub statements: Vec<Stmt>,
214}
215
216impl Program {
217    /// Create a new program
218    pub fn new() -> Self {
219        Program {
220            statements: Vec::new(),
221        }
222    }
223
224    /// Add a statement to the program
225    pub fn add_statement(&mut self, stmt: Stmt) {
226        self.statements.push(stmt);
227    }
228}
229
230impl Default for Program {
231    fn default() -> Self {
232        Self::new()
233    }
234}