use std::fmt;
use crate::lexer::Token;
use crate::Rcvar;
#[derive(Clone, PartialEq, Debug)]
pub enum Ast {
Comparison {
offset: usize,
comparator: Comparator,
lhs: Box<Ast>,
rhs: Box<Ast>,
},
Condition {
offset: usize,
predicate: Box<Ast>,
then: Box<Ast>,
},
Identity {
offset: usize,
},
Expref {
offset: usize,
ast: Box<Ast>,
},
Flatten {
offset: usize,
node: Box<Ast>,
},
Function {
offset: usize,
name: String,
args: Vec<Ast>,
},
Field {
offset: usize,
name: String,
},
Index {
offset: usize,
idx: i32,
},
Literal {
offset: usize,
value: Rcvar,
},
MultiList {
offset: usize,
elements: Vec<Ast>,
},
MultiHash {
offset: usize,
elements: Vec<KeyValuePair>,
},
Not {
offset: usize,
node: Box<Ast>,
},
Projection {
offset: usize,
lhs: Box<Ast>,
rhs: Box<Ast>,
},
ObjectValues {
offset: usize,
node: Box<Ast>,
},
And {
offset: usize,
lhs: Box<Ast>,
rhs: Box<Ast>,
},
Or {
offset: usize,
lhs: Box<Ast>,
rhs: Box<Ast>,
},
Slice {
offset: usize,
start: Option<i32>,
stop: Option<i32>,
step: i32,
},
Subexpr {
offset: usize,
lhs: Box<Ast>,
rhs: Box<Ast>,
},
}
impl fmt::Display for Ast {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(fmt, "{:#?}", self)
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct KeyValuePair {
pub key: String,
pub value: Ast,
}
#[derive(Clone, PartialEq, Debug)]
pub enum Comparator {
Equal,
NotEqual,
LessThan,
LessThanEqual,
GreaterThan,
GreaterThanEqual,
}
impl From<Token> for Comparator {
fn from(token: Token) -> Self {
match token {
Token::Lt => Comparator::LessThan,
Token::Lte => Comparator::LessThanEqual,
Token::Gt => Comparator::GreaterThan,
Token::Gte => Comparator::GreaterThanEqual,
Token::Eq => Comparator::Equal,
Token::Ne => Comparator::NotEqual,
_ => panic!("Invalid token for comparator: {:?}", token),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn displays_pretty_printed_ast_node() {
let node = Ast::Field {
name: "abc".to_string(),
offset: 4,
};
assert_eq!(
"Field {\n offset: 4,\n name: \"abc\",\n}",
format!("{}", node)
);
}
}