cel-parser 0.10.1

An antlr-based parser for the Common Expression Language (CEL)
Documentation
use crate::reference::Val;
use std::collections::BTreeMap;

pub mod operators;

pub struct Ast {
    pub expr: IdedExpr,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub enum Expr {
    #[default]
    /// UnspecifiedExprKind represents an unset expression with no specified properties.
    Unspecified,

    /// CallKind represents a function call.
    Call(CallExpr),

    /// ComprehensionKind represents a comprehension expression generated by a macro.
    Comprehension(ComprehensionExpr),

    /// IdentKind represents a simple variable, constant, or type identifier.
    Ident(String),

    /// ListKind represents a list literal expression.
    List(ListExpr),

    /// LiteralKind represents a primitive scalar literal.
    Literal(Val),

    /// MapKind represents a map literal expression.
    Map(MapExpr),

    /// SelectKind represents a field selection expression.
    Select(SelectExpr),

    /// StructKind represents a struct literal expression.
    Struct(StructExpr),
}

#[derive(Clone, Debug, PartialEq)]
pub enum EntryExpr {
    StructField(StructFieldExpr),
    MapEntry(MapEntryExpr),
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct IdedExpr {
    pub id: u64,
    pub expr: Expr,
}

#[derive(Clone, Debug, PartialEq)]
pub struct IdedEntryExpr {
    pub id: u64,
    pub expr: EntryExpr,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct CallExpr {
    pub func_name: String,
    pub target: Option<Box<IdedExpr>>,
    pub args: Vec<IdedExpr>,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct SelectExpr {
    pub operand: Box<IdedExpr>,
    pub field: String,
    pub test: bool,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct StructExpr {
    pub type_name: String,
    pub entries: Vec<IdedEntryExpr>,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct MapExpr {
    pub entries: Vec<IdedEntryExpr>,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ListExpr {
    pub elements: Vec<IdedExpr>,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct StructFieldExpr {
    pub field: String,
    pub value: IdedExpr,
    pub optional: bool,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct MapEntryExpr {
    pub key: IdedExpr,
    pub value: IdedExpr,
    pub optional: bool,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ComprehensionExpr {
    pub iter_range: Box<IdedExpr>,
    pub iter_var: String,
    pub iter_var2: Option<String>,
    pub accu_var: String,
    pub accu_init: Box<IdedExpr>,
    pub loop_cond: Box<IdedExpr>,
    pub loop_step: Box<IdedExpr>,
    pub result: Box<IdedExpr>,
}

#[derive(Debug, Default)]
pub struct SourceInfo {
    offsets: BTreeMap<u64, OffsetRange>,
    pub source: String,
}

impl SourceInfo {
    pub fn add_offset(&mut self, id: u64, start: u32, stop: u32) {
        self.offsets.insert(id, OffsetRange { start, stop });
    }

    pub fn offset_for(&self, id: u64) -> Option<(u32, u32)> {
        self.offsets.get(&id).map(|range| (range.start, range.stop))
    }

    pub(crate) fn pos_for(&self, id: u64) -> Option<(isize, isize)> {
        match self.offset_for(id) {
            Some((start, _)) => {
                let start = start as isize;
                let mut offset = 0;
                let mut line = 0;
                for l in self.source.split_inclusive('\n') {
                    line += 1;
                    offset += l.len() as isize;
                    if start < offset {
                        return Some((line, start + (l.len() as isize) - offset + 1));
                    }
                }
                None
            }
            None => None,
        }
    }

    pub fn snippet(&self, line: isize) -> Option<&str> {
        self.source.lines().nth(line as usize)
    }
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct OffsetRange {
    pub start: u32,
    pub stop: u32,
}