use crate::val::{Val, ValDef};
use crate::parse::Expr;
use crate::object::ObjRef;
use crate::str::Buf;
use std::ops::Drop;
use std::vec;
#[derive(Debug, PartialEq, Eq)]
pub struct ArgVec {
this: Option<ObjRef>,
args: Vec<Val>,
extra: Vec<Val>,
}
impl ArgVec {
pub fn new(this: Option<ObjRef>, args: Vec<Val>, extra: Vec<Val>) -> Self {
Self {
this,
args,
extra,
}
}
}
#[derive(Debug)]
pub struct Args {
this: Option<ObjRef>,
it: vec::IntoIter<Val>,
extra_args: Vec<Val>,
}
impl From<ArgVec> for Args {
fn from(v: ArgVec) -> Self {
let ArgVec { this, args, extra } = v;
Self::new(this, args, extra)
}
}
impl Args {
pub fn new(this: Option<ObjRef>, args: Vec<Val>, extra_args: Vec<Val>) -> Self {
Self {
this,
it: args.into_iter(),
extra_args,
}
}
pub fn take_this(&mut self) -> ObjRef {
self.this.take().unwrap()
}
pub fn next(&mut self) -> Val {
self.it.next().unwrap()
}
pub fn extra_args(&mut self) -> Vec<Val> {
std::mem::take(&mut self.extra_args)
}
pub fn extra_len(&self) -> usize {
self.extra_args.len()
}
pub fn collect_extra_args<T>(&mut self) -> Vec<T> where T: From<Val> {
self.extra_args().into_iter().map(|x| -> T { x.into() } ).collect()
}
pub fn join_extra(&mut self, j: &[u8]) -> Val {
let cargs: Vec<Buf> = self.collect_extra_args();
let strs: Vec<&[u8]> = cargs.iter().map(|x| x.as_ref()).collect();
let ret = strs.join(j);
Val::Str(Buf::from(ret))
}
pub fn void(&mut self) {
loop {
if self.it.next().is_none() {
break;
}
}
self.extra_args = vec!();
}
}
impl Drop for Args {
fn drop(&mut self) {
assert!(self.this.is_none(), "Method didn't take ownership of this");
assert!(self.it.next().is_none(), "Function didn't consume all args");
assert!(self.extra_args.is_empty(), "Function didn't consume extra args");
}
}
#[derive(Debug)]
pub struct ArgExpr {
pub name: Option<String>,
pub expr: Expr,
}
impl ArgExpr {
pub fn new(name: Option<String>, expr: Expr) -> Self {
Self {
name,
expr,
}
}
}
#[derive(Debug)]
pub struct ArgSpec {
pub name: Option<String>,
pub val: Val,
}
impl ArgSpec {
pub fn new(name: Option<String>, val: Val) -> Self {
Self {
name,
val,
}
}
pub fn is_anon(&self) -> bool {
self.name.is_none()
}
}
impl From<ValDef> for ArgSpec {
fn from(val: ValDef) -> Self {
Self {
name: None,
val: Val::from(val),
}
}
}
impl From<bool> for ArgSpec {
fn from(val: bool) -> Self {
Self {
name: None,
val: Val::Bool(val),
}
}
}
impl From<u64> for ArgSpec {
fn from(val: u64) -> Self {
Self {
name: None,
val: Val::U64(val),
}
}
}
impl<T> From<&T> for ArgSpec where T: AsRef<[u8]> + ? Sized {
fn from(s: &T) -> Self {
Self {
name: None,
val: Val::Str(Buf::from(s)),
}
}
}
impl From<(&str, ValDef)> for ArgSpec {
fn from((name, val): (&str, ValDef)) -> Self {
Self {
name: Some(name.to_owned()),
val: Val::from(val),
}
}
}
impl From<(&str, bool)> for ArgSpec {
fn from((name, val): (&str, bool)) -> Self {
Self {
name: Some(name.to_owned()),
val: Val::from(val),
}
}
}