toasty-core 0.3.0

Core types, schema representations, and driver interface for Toasty
Documentation
use super::{Expr, Value};

/// A list of expressions.
///
/// Represents an ordered collection of expressions that evaluate to a list of
/// values.
///
/// # Examples
///
/// ```text
/// list(a, b, c)  // a list containing expressions a, b, and c
/// ```
#[derive(Debug, Clone, PartialEq)]
pub struct ExprList {
    /// The expressions in the list.
    pub items: Vec<Expr>,
}

impl Expr {
    /// Creates a list expression from an iterator of items convertible to [`Expr`].
    pub fn list<T>(items: impl IntoIterator<Item = T>) -> Self
    where
        T: Into<Self>,
    {
        ExprList {
            items: items.into_iter().map(Into::into).collect(),
        }
        .into()
    }

    /// Creates a list expression from a pre-built vector of expressions.
    pub fn list_from_vec(items: Vec<Self>) -> Self {
        ExprList { items }.into()
    }

    /// Returns `true` if this expression is a list (either `Expr::List` or
    /// `Expr::Value(Value::List(...))`).
    pub fn is_list(&self) -> bool {
        matches!(self, Self::List(_) | Self::Value(Value::List(_)))
    }

    /// Returns `true` if this expression is an empty list.
    pub fn is_list_empty(&self) -> bool {
        match self {
            Self::List(list) => list.items.is_empty(),
            Self::Value(Value::List(list)) => list.is_empty(),
            _ => false,
        }
    }

    /// Returns a reference to the inner [`ExprList`].
    ///
    /// # Panics
    ///
    /// Panics if `self` is not `Expr::List`.
    #[track_caller]
    pub fn as_list_unwrap(&self) -> &ExprList {
        match self {
            Self::List(list) => list,
            _ => panic!("expected Expr::List(..) but was {self:#?}"),
        }
    }

    /// Returns a mutable reference to the inner [`ExprList`].
    ///
    /// # Panics
    ///
    /// Panics if `self` is not `Expr::List`.
    #[track_caller]
    pub fn as_list_mut_unwrap(&mut self) -> &mut ExprList {
        match self {
            Self::List(list) => list,
            _ => panic!("expected Expr::List(..) but was {self:#?}"),
        }
    }

    /// Consumes the expression, returning `Some(ExprList)` if it is a list,
    /// or `None` otherwise.
    pub fn into_list(self) -> Option<ExprList> {
        match self {
            Self::List(list) => Some(list),
            _ => None,
        }
    }
}

impl ExprList {
    /// Returns `true` if the list contains no expressions.
    pub fn is_empty(&self) -> bool {
        self.items.is_empty()
    }

    /// Returns the number of expressions in the list.
    pub fn len(&self) -> usize {
        self.items.len()
    }
}

impl From<ExprList> for Expr {
    fn from(value: ExprList) -> Self {
        Self::List(value)
    }
}

impl From<Vec<Self>> for Expr {
    fn from(value: Vec<Self>) -> Self {
        Self::list_from_vec(value)
    }
}