Lines
94.44 %
Functions
64 %
Branches
100 %
use supp_macro::command;
// Test the new pure typed system with no HashMap usage
#[derive(Debug)]
pub enum CmdError {
Args(String),
}
impl std::fmt::Display for CmdError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
impl std::error::Error for CmdError {}
pub enum CmdResult {
Success(String),
// Progressive types approach - no unified CommandArgs struct needed!
// Test command with mixed required and optional arguments - pure typed
command! {
CreateUser {
#[required]
name: String,
age: i64,
#[optional]
email: String,
is_admin: bool,
} => {
let email_str = email.map_or("no email".to_string(), |e| e);
let admin_str = is_admin.map_or("false".to_string(), |a| a.to_string());
Ok(Some(CmdResult::Success(format!(
"User: {} (age: {}), email: {}, admin: {}",
name, age, email_str, admin_str
))))
// Test command with no arguments
GetVersion {
Ok(Some(CmdResult::Success("Version 1.0.0".to_string())))
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_pure_typed_system() {
// ✅ Progressive types - pure value-based argument passing
let result = CreateUser::new()
.name("Alice".to_string())
.age(30)
.email("alice@example.com".to_string())
.is_admin(true)
.run()
.await
.unwrap();
if let Some(CmdResult::Success(msg)) = result {
assert!(msg.contains("Alice"));
assert!(msg.contains("30"));
assert!(msg.contains("alice@example.com"));
assert!(msg.contains("true"));
} else {
panic!("Expected success result");
async fn test_no_args_command() {
let result = GetVersion::new().run().await.unwrap();
assert_eq!(msg, "Version 1.0.0");
async fn test_optional_args_none() {
.name("Bob".to_string())
.age(25)
assert!(msg.contains("Bob"));
assert!(msg.contains("25"));
assert!(msg.contains("no email"));
assert!(msg.contains("false"));
#[test]
fn test_compile_time_validation() {
// ✅ Progressive types - all validation happens at compile time
let _runner = CreateUser::new()
.name("Charlie".to_string())
.age(35)
.email("charlie@example.com".to_string());
// The following would be compile errors with progressive types:
// let _invalid = CreateUser::new()
// .name("Dave".to_string())
// .run(); // Missing required field 'age' - compile error!
// let _invalid2 = CreateUser::new()
// .name(123) // Wrong type - compile error!
// .age(40);