use std::sync::Arc;
use ordermap::OrderMap;
use crate::tree::ast::{
expression::{Expression, FunctionCall},
identifier::{ParsedSimpleIdentifier, SimpleIdentifier},
node::Span,
};
use super::{ExpressionBuilder, IntoExpressionBuilder};
#[derive(Debug)]
pub struct FunctionCallBuilder {
name: SimpleIdentifier,
positional_args: Vec<Box<dyn ExpressionBuilder>>,
named_args: OrderMap<String, Box<dyn ExpressionBuilder>>,
}
impl FunctionCallBuilder {
pub fn new(name: impl Into<String>) -> Self {
let name_str = name.into();
Self {
name: SimpleIdentifier::new(&name_str),
positional_args: Vec::new(),
named_args: OrderMap::new(),
}
}
pub fn arg(mut self, arg: impl IntoExpressionBuilder) -> Self {
self.positional_args.push(arg.into_expression_builder());
self
}
pub fn args(mut self, args: impl IntoIterator<Item = impl IntoExpressionBuilder>) -> Self {
for arg in args {
self.positional_args.push(arg.into_expression_builder());
}
self
}
pub fn named_arg(mut self, name: impl Into<String>, arg: impl IntoExpressionBuilder) -> Self {
self.named_args
.insert(name.into(), arg.into_expression_builder());
self
}
}
impl ExpressionBuilder for FunctionCallBuilder {
fn build(&self) -> Expression {
let positional_args = self
.positional_args
.iter()
.map(|arg| Arc::new(arg.build()))
.collect();
let named_args = self
.named_args
.iter()
.map(|(name, arg)| {
let ident = ParsedSimpleIdentifier::Valid(SimpleIdentifier::new(name));
(ident, Arc::new(arg.build()))
})
.collect();
Expression {
span: Span::NONE,
kind: FunctionCall {
name: ParsedSimpleIdentifier::Valid(self.name.clone()),
positional_args,
named_args,
}
.into(),
}
}
}
impl IntoExpressionBuilder for FunctionCallBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
pub fn call(name: impl Into<String>) -> FunctionCallBuilder {
FunctionCallBuilder::new(name)
}