Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binary search and Result overriding -> RResult #45

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .zetch.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Bash {
}

/// Execute the current contents of the bash script.
pub fn run(self) -> Result<BashOut, BashErr> {
pub fn run(self) -> RResult<BashOut, BashErr> {
if self.cmds.is_empty() {
return Ok(BashOut::empty());
}
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/bash_out.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl BashOut {
}

/// Throw an error if the last command run was not successful.
pub fn throw_on_bad_code<T: error_stack::Context>(&self, err_variant: T) -> Result<(), T> {
pub fn throw_on_bad_code<T: error_stack::Context>(&self, err_variant: T) -> RResult<(), T> {
if self.success() {
Ok(())
} else {
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/builtins/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
};

/// https://www.gnu.org/software/bash/manual/bash.html#index-cd
pub fn cd(shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
pub fn cd(shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
macro_rules! hd {
() => {
if let Ok(hd) = shell.home_dir() {
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/builtins/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};

/// https://www.gnu.org/software/bash/manual/bash.html#index-echo
pub fn echo(_shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
pub fn echo(_shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
let mut newline = true;

let mut stdout = String::new();
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/builtins/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
/// Exit the shell, returning a status of n to the shell's parent.
/// If n is omitted, the exit status is that of the last command executed.
/// Any trap on EXIT is executed before the shell terminates.
pub fn exit(shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
pub fn exit(shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
let exit_code = if args.is_empty() {
// Last code
shell.code()
Expand Down
4 changes: 2 additions & 2 deletions rust/bitbazaar/cli/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::prelude::*;
/// - Performance
/// - Needs to implement the pseudo rust shell
/// - Windows compatibility - all implement builtins conform to linux/mac/bash expected usage.
pub type Builtin = fn(&mut Shell, &[String]) -> Result<BashOut, BuiltinErr>;
pub type Builtin = fn(&mut Shell, &[String]) -> RResult<BashOut, BuiltinErr>;

/// Helper for creating BashOut with an error code and writing to stderr.
macro_rules! bad_call {
Expand All @@ -41,7 +41,7 @@ pub static BUILTINS: Lazy<HashMap<&'static str, Builtin>> = Lazy::new(|| {
});

#[cfg(test)]
fn std_err_echo(_shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
fn std_err_echo(_shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
use super::CmdResult;

Ok(CmdResult::new("", 0, "", args.join(" ")).into())
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/builtins/pwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};

/// https://www.gnu.org/software/bash/manual/bash.html#index-pwd
pub fn pwd(shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
pub fn pwd(shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
if !args.is_empty() {
return Err(
err!(BuiltinErr::Unsupported).attach_printable("pwd: options are not supported")
Expand Down
2 changes: 1 addition & 1 deletion rust/bitbazaar/cli/builtins/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};

/// https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
pub fn set(shell: &mut Shell, args: &[String]) -> Result<BashOut, BuiltinErr> {
pub fn set(shell: &mut Shell, args: &[String]) -> RResult<BashOut, BuiltinErr> {
if let Some(arg) = args.first() {
match arg.as_str() {
"+e" => {
Expand Down
10 changes: 5 additions & 5 deletions rust/bitbazaar/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ mod tests {
#[case] exp_sterr: Option<&str>, // Only check if Some()
#[case] test_on_windows: bool, // Only check if Some()
#[allow(unused_variables)] logging: (),
) -> Result<(), AnyErr> {
) -> RResult<(), AnyErr> {
if cfg!(windows) && !test_on_windows {
return Ok(());
}
Expand Down Expand Up @@ -232,7 +232,7 @@ mod tests {
#[case] exp_std_all: S,
#[case] code: i32,
#[allow(unused_variables)] logging: (),
) -> Result<(), AnyErr> {
) -> RResult<(), AnyErr> {
let mut bash = Bash::new();
for cmd in cmds.into() {
bash = bash.cmd(cmd);
Expand All @@ -246,7 +246,7 @@ mod tests {

/// Confirm setting a custom working dir on the builder works plus when changing with cd in bash.
#[rstest]
fn test_run_dir(#[allow(unused_variables)] logging: ()) -> Result<(), AnyErr> {
fn test_run_dir(#[allow(unused_variables)] logging: ()) -> RResult<(), AnyErr> {
let temp_dir = tempfile::tempdir().change_context(AnyErr)?;
// normalise to make sure absolute (as pwd should always be absolute)
let temp_dir_pb = temp_dir
Expand Down Expand Up @@ -287,7 +287,7 @@ mod tests {

/// Confirm setting env vars on the builder work.
#[rstest]
fn test_builder_env(#[allow(unused_variables)] logging: ()) -> Result<(), AnyErr> {
fn test_builder_env(#[allow(unused_variables)] logging: ()) -> RResult<(), AnyErr> {
let res = Bash::new()
.env("FOO", "bar")
.env("BAZ", "qux")
Expand All @@ -301,7 +301,7 @@ mod tests {

// Confirm when both when doesn't error but not all commands run AND when Bash errors the final command that was attempted is accessible and printable.
#[rstest]
fn test_error_source_attached(#[allow(unused_variables)] logging: ()) -> Result<(), AnyErr> {
fn test_error_source_attached(#[allow(unused_variables)] logging: ()) -> RResult<(), AnyErr> {
let err_cmd = "ab||][/?cd";

// Confirm that when bash itself fails (i.e. invalid syntax), the source is attached to the error:
Expand Down
10 changes: 5 additions & 5 deletions rust/bitbazaar/cli/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn handle_redirect(
shell: &mut Shell,
last_out: Option<&mut RunnerBashOut>,
redirect: ast::DefaultRedirect,
) -> Result<RunnerBashOut, ShellErr> {
) -> RResult<RunnerBashOut, ShellErr> {
Ok(match redirect {
ast::Redirect::Write(fd, name) => {
let dest = Target::new(shell, name)?.set_write();
Expand Down Expand Up @@ -75,7 +75,7 @@ enum TargetVariant {
}

impl Target {
fn new(shell: &mut Shell, name: TopLevelWord<String>) -> Result<Self, ShellErr> {
fn new(shell: &mut Shell, name: TopLevelWord<String>) -> RResult<Self, ShellErr> {
let name = shell.process_complex_word(&name.0)?;

if name == "/dev/stdin" || name == "0" {
Expand Down Expand Up @@ -153,7 +153,7 @@ enum Data {
}

impl Data {
fn new(last: Option<&mut RunnerBashOut>, fd: Option<u16>) -> Result<Self, ShellErr> {
fn new(last: Option<&mut RunnerBashOut>, fd: Option<u16>) -> RResult<Self, ShellErr> {
let fd = fd.unwrap_or(1);

Ok(match fd {
Expand Down Expand Up @@ -204,7 +204,7 @@ impl Data {
})
}

fn submit(self, shell: &Shell, dest: Target) -> Result<RunnerBashOut, ShellErr> {
fn submit(self, shell: &Shell, dest: Target) -> RResult<RunnerBashOut, ShellErr> {
let mut conc = ConcreteOutput::default();

match dest.variant {
Expand Down Expand Up @@ -272,7 +272,7 @@ impl Data {
Ok(RunnerBashOut::Concrete(conc))
}

fn write(self, mut writer: impl Write) -> Result<(), ShellErr> {
fn write(self, mut writer: impl Write) -> RResult<(), ShellErr> {
match self {
Data::StdoutHandle(mut h) => {
std::io::copy(&mut h, &mut writer).change_context(ShellErr::InternalError)?;
Expand Down
8 changes: 4 additions & 4 deletions rust/bitbazaar/cli/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct ConcreteOutput {
}

impl RunnerBashOut {
fn into_shell(self, shell: &mut Shell) -> Result<(), ShellErr> {
fn into_shell(self, shell: &mut Shell) -> RResult<(), ShellErr> {
match self {
RunnerBashOut::Concrete(conc) => {
if let Some(stdout) = conc.stdout {
Expand Down Expand Up @@ -99,7 +99,7 @@ impl From<BashOut> for RunnerBashOut {

impl PipeRunner {
/// Add a new command to the runner.
pub fn add(&mut self, args: Vec<String>) -> Result<(), ShellErr> {
pub fn add(&mut self, args: Vec<String>) -> RResult<(), ShellErr> {
let first_arg = args
.first()
.ok_or_else(|| err!(ShellErr::InternalError, "No command provided"))?
Expand All @@ -125,7 +125,7 @@ impl PipeRunner {
Ok(())
}

pub fn add_redirect(&mut self, redirect: &ast::DefaultRedirect) -> Result<(), ShellErr> {
pub fn add_redirect(&mut self, redirect: &ast::DefaultRedirect) -> RResult<(), ShellErr> {
self.commands.push(VariCommand::Redirect(redirect.clone()));
Ok(())
}
Expand All @@ -134,7 +134,7 @@ impl PipeRunner {
self.commands.push(VariCommand::PipedStdout(stdout));
}

pub fn run(mut self, shell: &mut Shell) -> Result<(), ShellErr> {
pub fn run(mut self, shell: &mut Shell) -> RResult<(), ShellErr> {
for command in self.commands.into_iter() {
let last_out = self.outputs.last_mut();
let next_out: RunnerBashOut = match command {
Expand Down
38 changes: 19 additions & 19 deletions rust/bitbazaar/cli/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl From<Shell> for BashOut {
}

impl Shell {
pub fn new(env: HashMap<String, String>, root_dir: Option<PathBuf>) -> Result<Self, ShellErr> {
pub fn new(env: HashMap<String, String>, root_dir: Option<PathBuf>) -> RResult<Self, ShellErr> {
let mut shell = Self {
cmd_results: Vec::new(),
root_dir: None,
Expand All @@ -66,7 +66,7 @@ impl Shell {
Ok(shell)
}

pub fn execute_command_strings(&mut self, commands: Vec<String>) -> Result<(), ShellErr> {
pub fn execute_command_strings(&mut self, commands: Vec<String>) -> RResult<(), ShellErr> {
// Whilst all commands could be given to the parser together (newline separated),
// and run internally by the shell in a single function call,
// that mean's the source command string that causes an issues would be lost
Expand All @@ -88,7 +88,7 @@ impl Shell {

let parsed_top_cmds = parser
.into_iter()
.collect::<core::result::Result<Vec<_>, _>>()
.collect::<Result<Vec<_>, _>>()
.change_context(ShellErr::BashSyntaxError)?;

// Run the command:
Expand Down Expand Up @@ -145,7 +145,7 @@ impl Shell {
self.code
}

pub fn active_dir(&self) -> Result<PathBuf, ShellErr> {
pub fn active_dir(&self) -> RResult<PathBuf, ShellErr> {
if let Some(root_dir) = &self.root_dir {
Ok(root_dir.clone())
} else {
Expand All @@ -154,7 +154,7 @@ impl Shell {
}
}

pub fn chdir(&mut self, new_root_dir: PathBuf) -> Result<(), ShellErr> {
pub fn chdir(&mut self, new_root_dir: PathBuf) -> RResult<(), ShellErr> {
// normalise to ensure its absolute (to not break e.g. pwd)
self.root_dir = Some(
new_root_dir
Expand All @@ -176,7 +176,7 @@ impl Shell {
}
}

fn run_top_cmds(&mut self, cmds: Vec<ast::TopLevelCommand<String>>) -> Result<(), ShellErr> {
fn run_top_cmds(&mut self, cmds: Vec<ast::TopLevelCommand<String>>) -> RResult<(), ShellErr> {
// Each res equates to a line in a multi line bash script. E.g. a single line command will only have one res.
for cmd in cmds {
match cmd.0 {
Expand Down Expand Up @@ -219,7 +219,7 @@ impl Shell {
Ok(())
}

fn run_listable_command(&mut self, cmd: ast::DefaultListableCommand) -> Result<(), ShellErr> {
fn run_listable_command(&mut self, cmd: ast::DefaultListableCommand) -> RResult<(), ShellErr> {
let mut pipe_runner = PipeRunner::default();

match cmd {
Expand All @@ -246,7 +246,7 @@ impl Shell {
&mut self,
pipe_runner: &mut PipeRunner,
cmd: &ast::DefaultPipeableCommand,
) -> Result<(), ShellErr> {
) -> RResult<(), ShellErr> {
match cmd {
ast::PipeableCommand::Simple(cmd) => self.add_simple_command(pipe_runner, cmd)?,
ast::PipeableCommand::Compound(compound) => {
Expand Down Expand Up @@ -309,7 +309,7 @@ impl Shell {
&mut self,
pipe_runner: &mut PipeRunner,
cmd: &ast::DefaultSimpleCommand,
) -> Result<(), ShellErr> {
) -> RResult<(), ShellErr> {
let mut env = Vec::<(String, String)>::new();

for item in cmd.redirects_or_env_vars.iter() {
Expand Down Expand Up @@ -358,7 +358,7 @@ impl Shell {
pub fn process_complex_word(
&mut self,
word: &ast::DefaultComplexWord,
) -> Result<String, ShellErr> {
) -> RResult<String, ShellErr> {
match word {
ast::ComplexWord::Single(word) => self.process_word(word, None, false),
ast::ComplexWord::Concat(words) => {
Expand All @@ -371,7 +371,7 @@ impl Shell {
concat_state.active = index;
self.process_word(word, Some(&concat_state), false)
})
.collect::<Result<Vec<_>, _>>()?
.collect::<RResult<Vec<_>, _>>()?
.join("");
Ok(result)
}
Expand All @@ -383,7 +383,7 @@ impl Shell {
word: &ast::DefaultWord,
concat_state: Option<&'_ WordConcatState<'_>>,
is_lookaround: bool,
) -> Result<String, ShellErr> {
) -> RResult<String, ShellErr> {
Ok(match word {
// Single quoted means no processing inside needed:
ast::Word::SingleQuoted(word) => word.to_string(),
Expand All @@ -393,14 +393,14 @@ impl Shell {
ast::Word::DoubleQuoted(words) => words
.iter()
.map(|word| self.process_simple_word(word, concat_state, is_lookaround))
.collect::<Result<Vec<_>, _>>()?
.collect::<RResult<Vec<_>, _>>()?
.into_iter()
.collect::<Vec<_>>()
.join(""),
})
}

pub fn home_dir(&self) -> Result<PathBuf, ShellErr> {
pub fn home_dir(&self) -> RResult<PathBuf, ShellErr> {
homedir::get_my_home()
.change_context(ShellErr::InternalError)?
.ok_or_else(|| err!(ShellErr::InternalError))
Expand All @@ -411,7 +411,7 @@ impl Shell {
word: &ast::DefaultSimpleWord,
concat_state: Option<&'_ WordConcatState<'_>>,
is_lookaround: bool,
) -> Result<String, ShellErr> {
) -> RResult<String, ShellErr> {
Ok(match word {
ast::SimpleWord::Literal(lit) => lit.to_string(),
ast::SimpleWord::Escaped(a) => a.to_string(),
Expand Down Expand Up @@ -442,7 +442,7 @@ impl Shell {
})
}

fn process_param(&mut self, param: &ast::DefaultParameter) -> Result<String, ShellErr> {
fn process_param(&mut self, param: &ast::DefaultParameter) -> RResult<String, ShellErr> {
Ok(match param {
ast::Parameter::Var(var) => {
// First try variables in current shell, otherwise try env:
Expand Down Expand Up @@ -485,7 +485,7 @@ impl Shell {
fn process_substitution(
&mut self,
sub: &ast::DefaultParameterSubstitution,
) -> Result<String, ShellErr> {
) -> RResult<String, ShellErr> {
match sub {
ast::ParameterSubstitution::Command(cmds) => {
// Run the nested command, from my tests with terminal:
Expand Down Expand Up @@ -563,7 +563,7 @@ impl Shell {
&mut self,
concat_state: Option<&'_ WordConcatState<'_>>,
is_lookaround: bool,
) -> Result<bool, ShellErr> {
) -> RResult<bool, ShellErr> {
// Handle infinite loop:
if is_lookaround {
return Ok(false);
Expand All @@ -589,7 +589,7 @@ impl Shell {
}

/// Helper to create unsupported error message.
fn unsup(desc: &'static str) -> error_stack::Report<ShellErr> {
fn unsup(desc: &'static str) -> Report<ShellErr> {
err!(
ShellErr::BashFeatureUnsupported,
"Used valid bash syntax not implemented: {}",
Expand Down
Loading
Loading