use crate::expr::{Expression, IntoIter, Iter, IterMut};
use crate::repr::{Decor, Decorate, Decorated, SetSpan, Span};
use crate::{Ident, RawString};
use std::ops::Range;
#[derive(Debug, Clone, Eq)]
pub struct FuncCall {
pub ident: Decorated<Ident>,
pub args: FuncArgs,
decor: Decor,
span: Option<Range<usize>>,
}
impl FuncCall {
pub fn new(ident: Decorated<Ident>, args: FuncArgs) -> FuncCall {
FuncCall {
ident,
args,
decor: Decor::default(),
span: None,
}
}
pub(crate) fn despan(&mut self, input: &str) {
self.decor.despan(input);
self.ident.decor_mut().despan(input);
self.args.despan(input);
}
}
impl PartialEq for FuncCall {
fn eq(&self, other: &Self) -> bool {
self.ident == other.ident && self.args == other.args
}
}
#[derive(Debug, Clone, Eq, Default)]
pub struct FuncArgs {
args: Vec<Expression>,
expand_final: bool,
trailing: RawString,
trailing_comma: bool,
decor: Decor,
span: Option<Range<usize>>,
}
impl FuncArgs {
#[inline]
pub fn new() -> Self {
FuncArgs::default()
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
FuncArgs {
args: Vec::with_capacity(capacity),
..Default::default()
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.args.is_empty()
}
#[inline]
pub fn len(&self) -> usize {
self.args.len()
}
#[inline]
pub fn clear(&mut self) {
self.args.clear();
}
#[inline]
pub fn get(&self, index: usize) -> Option<&Expression> {
self.args.get(index)
}
#[inline]
pub fn get_mut(&mut self, index: usize) -> Option<&mut Expression> {
self.args.get_mut(index)
}
#[inline]
pub fn insert(&mut self, index: usize, arg: impl Into<Expression>) {
self.args.insert(index, arg.into());
}
#[inline]
pub fn pop(&mut self) -> Option<Expression> {
self.args.pop()
}
#[inline]
pub fn push(&mut self, arg: impl Into<Expression>) {
self.args.push(arg.into());
}
#[inline]
pub fn remove(&mut self, index: usize) -> Expression {
self.args.remove(index)
}
#[inline]
pub fn iter(&self) -> Iter<'_> {
Box::new(self.args.iter())
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_> {
Box::new(self.args.iter_mut())
}
#[inline]
pub fn expand_final(&self) -> bool {
self.expand_final
}
#[inline]
pub fn set_expand_final(&mut self, yes: bool) {
self.expand_final = yes;
}
#[inline]
pub fn trailing(&self) -> &RawString {
&self.trailing
}
#[inline]
pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
self.trailing = trailing.into();
}
#[inline]
pub fn trailing_comma(&self) -> bool {
self.trailing_comma
}
#[inline]
pub fn set_trailing_comma(&mut self, yes: bool) {
self.trailing_comma = yes;
}
pub(crate) fn despan(&mut self, input: &str) {
self.decor.despan(input);
for arg in &mut self.args {
arg.despan(input);
}
self.trailing.despan(input);
}
}
impl PartialEq for FuncArgs {
fn eq(&self, other: &Self) -> bool {
self.args == other.args
&& self.trailing_comma == other.trailing_comma
&& self.trailing == other.trailing
}
}
impl From<Vec<Expression>> for FuncArgs {
fn from(args: Vec<Expression>) -> Self {
FuncArgs {
args,
..Default::default()
}
}
}
impl<T> Extend<T> for FuncArgs
where
T: Into<Expression>,
{
fn extend<I>(&mut self, iterable: I)
where
I: IntoIterator<Item = T>,
{
let iter = iterable.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.args.reserve(reserve);
iter.for_each(|v| self.push(v));
}
}
impl<T> FromIterator<T> for FuncArgs
where
T: Into<Expression>,
{
fn from_iter<I>(iterable: I) -> Self
where
I: IntoIterator<Item = T>,
{
let iter = iterable.into_iter();
let lower = iter.size_hint().0;
let mut func_args = FuncArgs::with_capacity(lower);
func_args.extend(iter);
func_args
}
}
impl IntoIterator for FuncArgs {
type Item = Expression;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(self.args.into_iter())
}
}
impl<'a> IntoIterator for &'a FuncArgs {
type Item = &'a Expression;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a mut FuncArgs {
type Item = &'a mut Expression;
type IntoIter = IterMut<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
decorate_impl!(FuncCall, FuncArgs);
span_impl!(FuncCall, FuncArgs);