fosk 0.2.0

In-memory SQL-like query engine and lightweight data store for testing and prototyping.
Documentation
use crate::parser::ast::ScalarExpr;
use std::fmt;

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Function {
    pub name: String,
    pub args: Vec<ScalarExpr>,
    pub distinct: bool,
}

impl fmt::Display for Function {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let args = self
            .args
            .iter()
            .map(|a| format!("{}", a))
            .collect::<Vec<_>>()
            .join(", ");
        if self.distinct {
            write!(f, "{}(distinct {})", self.name, args)
        } else {
            write!(f, "{}({})", self.name, args)
        }
    }
}

impl fmt::Debug for Function {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Function({})", self)
    }
}

#[cfg(test)]
mod tests {
    use super::Function;
    use crate::parser::ast::{Literal, ScalarExpr};

    fn int_arg(value: i64) -> ScalarExpr {
        ScalarExpr::Literal(Literal::Int(value))
    }

    fn string_arg(value: &str) -> ScalarExpr {
        ScalarExpr::Literal(Literal::String(value.to_string()))
    }

    #[test]
    fn display_formats_regular_function_call() {
        let function = Function {
            name: "lower".to_string(),
            args: vec![string_arg("Ada")],
            distinct: false,
        };

        assert_eq!(function.to_string(), "lower(lit: s: \"Ada\")");
        assert_eq!(
            format!("{:?}", function),
            "Function(lower(lit: s: \"Ada\"))"
        );
    }

    #[test]
    fn display_formats_distinct_function_call_with_multiple_args() {
        let function = Function {
            name: "count".to_string(),
            args: vec![int_arg(1), string_arg("Ada")],
            distinct: true,
        };

        assert_eq!(
            function.to_string(),
            "count(distinct lit: i: 1, lit: s: \"Ada\")"
        );
    }
}