avid 0.6.1

A plug-and-play scripting language
Documentation
use std::fmt;

type VecObj = Vec<Object>;

enum_type! {
    /// The possible types in an Avid program.
    Object {
        /// A number.
        Num(isize),
        /// A string
        String(String),
        /// A boolean
        Bool(bool),
        /// A list of objects
        List(VecObj)
    }
}

impl Clone for Object {
    fn clone(&self) -> Self {
        match self {
            Self::Num(i) => Self::Num(*i),
            Self::String(s) => Self::String(s.clone()),
            Self::Bool(b) => Self::Bool(*b),
            Self::List(l) => Self::List(l.clone()),
        }
    }
}

impl Object {
    /// Whether the object evaluates to "true" in a condition.
    ///
    /// For now, the only instances that evaluate to `false` are `false`, `""` and
    /// `0`.
    pub fn truthy(&self) -> bool {
        let cond = match self {
            Object::Num(n) => *n == 0,
            Object::String(s) => s.as_str() == "",
            Object::Bool(b) => !*b,
            Object::List(l) => l.is_empty(),
        };
        !cond
    }
}

impl fmt::Display for Object {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Num(n) => write!(f, "{n}"),
            Self::String(s) => write!(f, "{s}"),
            Self::Bool(b) => write!(f, "{b}"),
            Self::List(l) => {
                write!(f, "[")?;
                for (idx, obj) in l.iter().enumerate() {
                    if idx > 0 {
                        write!(f, ", ")?;
                    }
                    write!(f, "{obj}")?;
                }
                write!(f, "]")
            }
        }
    }
}