#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![doc(html_root_url = "https://docs.rs/molt/0.3.0")]
#![doc(html_logo_url = "https://github.com/wduquette/molt/raw/master/MoltLogo.png")]
extern crate alloc;
use alloc::{string::ToString as _, borrow::ToOwned as _};
pub use crate::interp::Interp;
#[cfg(all(feature = "closure-commands", any(test, feature = "std")))]
pub use crate::test_harness::test_harness;
pub use crate::types::*;
mod commands;
#[cfg(feature = "dict")]
pub mod dict;
mod eval_ptr;
#[cfg(feature = "expr")]
mod expr;
pub mod interp;
mod list;
mod tokenizer;
#[macro_use]
mod macros;
mod parser;
mod scope;
#[cfg(all(feature = "closure-commands", any(test, feature = "std")))]
pub mod test_harness;
pub mod types;
mod util;
pub mod value;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub use alloc::format;
#[cfg(feature = "std")]
#[doc(hidden)]
pub use std::format;
pub fn check_args(
namec: usize,
argv: &[Value],
min: usize,
max: usize,
argsig: &str,
) -> Result<(), Exception> {
assert!(namec >= 1);
assert!(min >= 1);
assert!(!argv.is_empty());
if argv.len() < min || (max > 0 && argv.len() > max) {
let cmd_tokens = Value::from(&argv[0..namec]);
molt_err!(
"wrong # args: should be \"{} {}\"",
cmd_tokens.to_string(),
argsig
)
} else {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_check_args() {
assert_ok(&check_args(1, &mklist(vec!["mycmd"].as_slice()), 1, 1, ""));
assert_ok(&check_args(
1,
&mklist(vec!["mycmd"].as_slice()),
1,
2,
"arg1",
));
assert_ok(&check_args(
1,
&mklist(vec!["mycmd", "data"].as_slice()),
1,
2,
"arg1",
));
assert_ok(&check_args(
1,
&mklist(vec!["mycmd", "data", "data2"].as_slice()),
1,
0,
"arg1",
));
assert_err(
&check_args(1, &mklist(vec!["mycmd"].as_slice()), 2, 2, "arg1"),
"wrong # args: should be \"mycmd arg1\"",
);
assert_err(
&check_args(
1,
&mklist(vec!["mycmd", "val1", "val2"].as_slice()),
2,
2,
"arg1",
),
"wrong # args: should be \"mycmd arg1\"",
);
}
fn mklist(argv: &[&'static str]) -> MoltList {
argv.iter().map(|s| Value::from(*s)).collect()
}
fn assert_err<T: PartialEq + core::fmt::Debug>(result: &Result<T, Exception>, msg: &'static str) {
assert_eq!(molt_err!(msg), *result);
}
fn assert_ok<T>(result: &Result<T, Exception>) {
assert!(result.is_ok(), "Result is not Ok");
}
}