use nu_protocol::{ ast::Call, engine::{EngineState, Stack}, FromValue, ShellError, }; use crate::eval_expression; pub trait CallExt { fn get_flag( &self, engine_state: &EngineState, stack: &mut Stack, name: &str, ) -> Result, ShellError>; fn rest( &self, engine_state: &EngineState, stack: &mut Stack, starting_pos: usize, ) -> Result, ShellError>; fn opt( &self, engine_state: &EngineState, stack: &mut Stack, pos: usize, ) -> Result, ShellError>; fn req( &self, engine_state: &EngineState, stack: &mut Stack, pos: usize, ) -> Result; } impl CallExt for Call { fn get_flag( &self, engine_state: &EngineState, stack: &mut Stack, name: &str, ) -> Result, ShellError> { if let Some(expr) = self.get_flag_expr(name) { let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result).map(Some) } else { Ok(None) } } fn rest( &self, engine_state: &EngineState, stack: &mut Stack, starting_pos: usize, ) -> Result, ShellError> { let mut output = vec![]; for expr in self.positional.iter().skip(starting_pos) { let result = eval_expression(engine_state, stack, expr)?; output.push(FromValue::from_value(&result)?); } Ok(output) } fn opt( &self, engine_state: &EngineState, stack: &mut Stack, pos: usize, ) -> Result, ShellError> { if let Some(expr) = self.nth(pos) { let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result).map(Some) } else { Ok(None) } } fn req( &self, engine_state: &EngineState, stack: &mut Stack, pos: usize, ) -> Result { if let Some(expr) = self.nth(pos) { let result = eval_expression(engine_state, stack, &expr)?; FromValue::from_value(&result) } else { Err(ShellError::AccessBeyondEnd( self.positional.len(), self.head, )) } } }