use super::Expression;
use crate::parsers::hcl::{Pair, Rule, ast::Str};
use self::object::Object;
pub mod object;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum ExprTerm<'i> {
String(Str<'i>),
Object(Object<'i>),
Tuple(Vec<Expression<'i>>),
Raw(Pair<'i>),
}
impl<'i> ExprTerm<'i> {
pub fn as_string(&self) -> Option<Str<'i>> {
if let Self::String(s) = self {
Some(*s)
} else {
None
}
}
pub fn as_object(&self) -> Option<&Object<'i>> {
if let Self::Object(obj) = self {
Some(obj)
} else {
None
}
}
pub fn as_tuple(&self) -> Option<&[Expression<'i>]> {
if let Self::Tuple(items) = self {
Some(items)
} else {
None
}
}
}
impl<'i> ExprTerm<'i> {
pub(super) fn process(pair: Pair<'i>) -> Self {
let mut items = pair.into_inner();
let expr = items.next().unwrap();
ExprTerm::process_expr(expr)
}
fn process_expr(pair: Pair<'i>) -> Self {
match pair.as_rule() {
Rule::StringLit => {
let span = pair.as_span();
let inner = pair.into_inner().next().unwrap();
let value = Str::new(span, inner.as_str());
ExprTerm::String(value)
}
Rule::Object => ExprTerm::Object(Object::process(pair)),
_ => ExprTerm::Raw(pair),
}
}
fn process_tuple(pair: Pair<'i>) -> Self {
let data = pair.into_inner().map(Expression::process).collect();
ExprTerm::Tuple(data)
}
}