From 6357209dc9ad199a0fb274011f73c9a922c670cc Mon Sep 17 00:00:00 2001 From: Xavier L'Heureux <xavier.lheureux@icloud.com> Date: Tue, 25 Jun 2019 14:42:04 -0400 Subject: [PATCH] Document the Status and add a man page for the fn builtin --- src/lib/builtins/functions.rs | 18 +++++++++++++++--- src/lib/builtins/helpers.rs | 17 +++++++++++++++++ src/lib/builtins/man_pages.rs | 1 + src/lib/builtins/mod.rs | 11 +++-------- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/lib/builtins/functions.rs b/src/lib/builtins/functions.rs index 5d2a68c3..b143b352 100644 --- a/src/lib/builtins/functions.rs +++ b/src/lib/builtins/functions.rs @@ -1,12 +1,24 @@ use super::Status; -use crate::shell::variables::Variables; +use crate as ion_shell; +use crate::{types, Shell}; +use builtins_proc::builtin; use std::io::{self, Write}; -pub fn print_functions(vars: &Variables<'_>) -> Status { +#[builtin( + names = "fn", + desc = "print a short description of every defined function", + man = " +SYNOPSIS + fn [ -h | --help ] + +DESCRIPTION + Prints all the defined functions along with their help, if provided" +)] +pub fn fn_(args: &[types::Str], shell: &mut Shell<'_>) -> Status { let stdout = io::stdout(); let stdout = &mut stdout.lock(); let _ = writeln!(stdout, "# Functions"); - for (fn_name, function) in vars.functions() { + for (fn_name, function) in shell.variables().functions() { let description = function.description(); if let Some(ref description) = description { let _ = writeln!(stdout, " {} -- {}", fn_name, description); diff --git a/src/lib/builtins/helpers.rs b/src/lib/builtins/helpers.rs index ad3b88dc..346f4f37 100644 --- a/src/lib/builtins/helpers.rs +++ b/src/lib/builtins/helpers.rs @@ -1,20 +1,32 @@ use super::{super::types, Value}; +/// The exit status of a command +/// +/// Provides some helpers for defining builtins like error messages and semantic constants #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)] pub struct Status(i32); impl Status { + /// Failed to execute a given command (a parsing/expansion error occured) pub const COULD_NOT_EXEC: Self = Status(126); + /// In builtins that output bools, indicates negation pub const FALSE: Self = Status(1); + /// The command does not exist pub const NO_SUCH_COMMAND: Self = Status(127); + /// The execution succeeded pub const SUCCESS: Self = Status(0); + /// The process was killed pub const TERMINATED: Self = Status(143); + /// In builtins that outputs bools, indicates that the result is true pub const TRUE: Self = Status(0); + /// Make an exit code out of a signal pub fn from_signal(signal: u8) -> Self { Status(i32::from(128 + signal)) } + /// From a raw exit code (native commands) pub fn from_exit_code(code: i32) -> Self { Status(code) } + /// A generic error occured. Prints an helper text pub fn error<T: AsRef<str>>(err: T) -> Self { let err = err.as_ref(); if !err.is_empty() { @@ -23,6 +35,7 @@ impl Status { Status(1) } + /// Wrong arguments submitted to the builtin pub fn bad_argument<T: AsRef<str>>(err: T) -> Self { let err = err.as_ref(); if !err.is_empty() { @@ -31,12 +44,16 @@ impl Status { Status(2) } + /// Indicates if the operation is successful pub fn is_success(self) -> bool { self.0 == 0 } + /// Indicates if the operation is unsuccessful pub fn is_failure(self) -> bool { self.0 != 0 } + /// Convert to a raw OS exit code pub fn as_os_code(self) -> i32 { self.0 } + /// Change true to false and false to true. Looses information pub fn toggle(&mut self) { self.0 = if self.is_success() { 1 } else { 0 }; } } diff --git a/src/lib/builtins/man_pages.rs b/src/lib/builtins/man_pages.rs index f0ed8ff9..0ef29d55 100644 --- a/src/lib/builtins/man_pages.rs +++ b/src/lib/builtins/man_pages.rs @@ -1,5 +1,6 @@ use crate::types; +/// Print the given help if the -h or --help argument are found pub fn check_help(args: &[types::Str], man_page: &'static str) -> bool { for arg in args { if arg == "-h" || arg == "--help" { diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs index f820471e..31563d54 100644 --- a/src/lib/builtins/mod.rs +++ b/src/lib/builtins/mod.rs @@ -1,3 +1,4 @@ +/// helpers for creating help pub mod man_pages; mod calc; @@ -21,7 +22,7 @@ pub use self::{ conditionals::{contains, ends_with, starts_with}, echo::builtin_echo, exists::builtin_exists, - functions::print_functions, + functions::builtin_fn_, helpers::Status, is::builtin_is, man_pages::check_help, @@ -156,7 +157,7 @@ impl<'a> BuiltinMap<'a> { /// /// Contains `fn`, `alias`, `unalias`, `drop`, `read` pub fn with_variables(&mut self) -> &mut Self { - self.add("fn", &builtin_fn, "Print list of functions") + self.add("fn", &builtin_fn_, "Print list of functions") .add("alias", &builtin_alias, "View, set or unset aliases") .add("unalias", &builtin_unalias, "Delete an alias") .add("drop", &builtin_drop, "Delete a variable") @@ -553,12 +554,6 @@ pub fn popd(args: &[types::Str], shell: &mut Shell<'_>) -> Status { } } -// TODO There is a man page for fn however the -h and --help flags are not -// checked for. -pub fn builtin_fn(_: &[types::Str], shell: &mut Shell<'_>) -> Status { - print_functions(shell.variables()) -} - struct EmptyCompleter; impl Completer for EmptyCompleter { -- GitLab