arcticpalette 0.1.0

A straightforward, lightweight version of clap.
Documentation
pub struct ArcticPalette {
  palettes: Vec<Palette>,
  fallback: Option<Palette>
}

struct Palette {
  name: String,
  handler: Box<dyn Fn(Command)>
}

pub struct Command {
  pub arguments: Vec<String>,
  pub flags: Vec<String>,
  pub command: String,
}

impl Command {
  pub fn new(raw: String) -> Self {
    let mut segments: Vec<String> = raw.split_whitespace().map(String::from).collect();
    let command = segments.remove(0);
    let mut flags: Vec<String> = Vec::new();
    let mut arguments: Vec<String> = Vec::new();
    for segment in &segments {
      if segment.starts_with("-") {
        flags.push(segment[1..].to_string());
      } else {
        arguments.push(segment.to_string());
      }
    }
    Command { arguments, command, flags }
  }
  pub fn get_cmd(&self) -> String {
    self.command.clone()
  }
  pub fn get_arg(&self, index: usize) -> Option<String> {
    self.arguments.get(index).cloned()
  }
  pub fn pop_arg(&mut self, index: usize) -> Option<String> {
    if index < self.arguments.len() {
      Some(self.arguments.remove(index))
    } else {
      None
    }
  }
  pub fn join_args(&self) -> String {
    self.arguments.join(" ")
  }
  pub fn get_flags(&self) -> Vec<String> {
    self.flags.clone()
  }
  pub fn has_flag(&self, flag: String) -> bool {
    self.flags.contains(&flag.to_string())
  }
}

impl ArcticPalette {
  pub const NOT_FOUND: usize = 200;
  pub const FALLBACK: usize = 201;
  pub const SUCCESS: usize = 100;
  pub fn new() -> Self {
    let palettes: Vec<Palette> = Vec::new();
    Self { palettes, fallback: None }
  }
  pub fn assign<F>(&mut self, name: String, handler: F)
  where F: Fn(Command) + 'static {
    let palette = Palette {
      name: name.to_lowercase(),
      handler: Box::new(handler)
    };
    self.palettes.push(palette);
  }
  pub fn assign_fallback<F>(&mut self, handler: F)
  where F: Fn(Command) + 'static {
    let palette = Palette {
      name: String::new(),
      handler: Box::new(handler)
    };
    self.fallback = Some(palette);
  }
  pub fn apply(&self, raw: String) -> usize {
    let cmd = Command::new(raw);
    if let Some(palette) = self.palettes.iter().find(|p| p.name == cmd.command) {
      (palette.handler)(cmd);
      ArcticPalette::SUCCESS
    } else {
      if let Some(fallback) = &self.fallback {
        (fallback.handler)(cmd);
        ArcticPalette::FALLBACK
      } else {
        ArcticPalette::NOT_FOUND
      }
    }
  }
}