use super::{format_arg, format_vararg};
use endbasic_core::*;
use std::borrow::Cow;
use std::cell::RefCell;
use std::rc::Rc;
pub(super) struct OutPositionalCommand {
metadata: Rc<CallableMetadata>,
output: Rc<RefCell<String>>,
}
impl OutPositionalCommand {
pub(super) fn new(output: Rc<RefCell<String>>) -> Rc<Self> {
Rc::from(Self {
metadata: CallableMetadataBuilder::new("OUT_POSITIONAL")
.with_syntax(&[(
&[
SingularArgSyntax::AnyValue(
AnyValueSyntax { name: Cow::Borrowed("arg1"), allow_missing: true },
ArgSepSyntax::OneOf(&[ArgSep::Long, ArgSep::Short]),
),
SingularArgSyntax::RequiredValue(
RequiredValueSyntax {
name: Cow::Borrowed("arg2"),
vtype: ExprType::Integer,
},
ArgSepSyntax::Exactly(ArgSep::As),
),
SingularArgSyntax::AnyValue(
AnyValueSyntax { name: Cow::Borrowed("arg3"), allow_missing: false },
ArgSepSyntax::End,
),
],
None,
)])
.test_build(),
output,
})
}
}
impl Callable for OutPositionalCommand {
fn metadata(&self) -> Rc<CallableMetadata> {
self.metadata.clone()
}
fn exec(&self, scope: Scope<'_>) -> CallResult<()> {
let mut output = self.output.borrow_mut();
let mut i = 0;
let (formatted, present, sep) = format_vararg(&scope, i);
assert_ne!(ArgSep::End, sep, "Command expects more arguments");
output.push_str(&formatted);
output.push('\n');
i += 1;
if present {
i += 1;
}
let formatted = format_arg(&scope, i, ExprType::Integer);
output.push_str(&formatted);
output.push('\n');
i += 1;
let (formatted, present, sep) = format_vararg(&scope, i);
assert!(present, "Last argument is not optional");
assert_eq!(ArgSep::End, sep, "No more arguments expected");
output.push_str(&formatted);
output.push('\n');
Ok(())
}
}