From deafab9c930ab092c4ee8abd4cbe09c7eb34aa22 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Sun, 8 Mar 2026 08:28:57 +0100 Subject: argument parsing --- src/run/builtin.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/run/mod.rs | 2 ++ 2 files changed, 50 insertions(+) (limited to 'src/run') diff --git a/src/run/builtin.rs b/src/run/builtin.rs index c9456cd..366aaa5 100644 --- a/src/run/builtin.rs +++ b/src/run/builtin.rs @@ -3,10 +3,49 @@ use std::sync::{Arc, Mutex}; use std::{env::*, fs::OpenOptions, path::PathBuf}; +use pish_derive::FromArgs; + use super::{Builtin, BuiltinError as Error, BuiltinResult as Result}; use crate::parse::CmdDisplay; use crate::*; +pub enum ArgParseError<'a> { + LeftoverArg(&'a [u8]), + MissingArg(&'static str), + MissingArgValue(&'static str), + ArgValueParseError(&'static str, String), +} + +pub trait ArgParse: Sized { + fn parse<'a>(args: &'a [BString]) -> std::result::Result>; +} + +fn args(args: &[BString], w: &mut dyn Write) -> std::result::Result { + let err = match T::parse(args) { + Ok(t) => return Ok(t), + Err(e) => e, + }; + + match err { + ArgParseError::LeftoverArg(items) => { + w.write_all(b"leftover argument: ")?; + w.write_all(items)?; + w.write_all(b"\n")?; + } + ArgParseError::MissingArg(arg) => { + write!(w, "argument `{arg}` is missing\n")?; + } + ArgParseError::MissingArgValue(arg) => { + write!(w, "argument `{arg}` is missing its value\n")?; + } + ArgParseError::ArgValueParseError(arg, err) => { + write!(w, "failed to parse value of `{arg}`: {err}")?; + } + } + + Err(Error::Exit(-2)) +} + pub struct cd; impl Builtin for cd { fn name(&self) -> &str { @@ -206,6 +245,15 @@ impl Builtin for builtins { } } +#[derive(FromArgs)] +struct HistoryArgs { + local: bool, + + here: bool, + at: Option, + // TODO: temporal control, i.e. before & after +} + pub struct history; impl Builtin for history { fn name(&self) -> &str { diff --git a/src/run/mod.rs b/src/run/mod.rs index 0b9aef8..d386590 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -155,6 +155,7 @@ impl Executor { Ok(Err(e)) => match e { BuiltinError::IO(_) => code = -1, BuiltinError::Exit(c) => code = c, + BuiltinError::ParseError(_) => code = -2, }, Err(_) => code = 127, } @@ -290,6 +291,7 @@ pub fn run(se: Arc>, cmd: Vec) { #[derive(Debug)] pub enum BuiltinError { IO(std::io::Error), + ParseError(&'static str), Exit(i32), } -- cgit v1.2.3