Skip to content
Snippets Groups Projects
Commit 6357209d authored by AdminXVII's avatar AdminXVII
Browse files

Document the Status and add a man page for the fn builtin

parent 2aee857d
No related branches found
No related tags found
No related merge requests found
use super::Status; 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}; 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 = io::stdout();
let stdout = &mut stdout.lock(); let stdout = &mut stdout.lock();
let _ = writeln!(stdout, "# Functions"); let _ = writeln!(stdout, "# Functions");
for (fn_name, function) in vars.functions() { for (fn_name, function) in shell.variables().functions() {
let description = function.description(); let description = function.description();
if let Some(ref description) = description { if let Some(ref description) = description {
let _ = writeln!(stdout, " {} -- {}", fn_name, description); let _ = writeln!(stdout, " {} -- {}", fn_name, description);
......
use super::{super::types, Value}; 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)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
pub struct Status(i32); pub struct Status(i32);
impl Status { impl Status {
/// Failed to execute a given command (a parsing/expansion error occured)
pub const COULD_NOT_EXEC: Self = Status(126); pub const COULD_NOT_EXEC: Self = Status(126);
/// In builtins that output bools, indicates negation
pub const FALSE: Self = Status(1); pub const FALSE: Self = Status(1);
/// The command does not exist
pub const NO_SUCH_COMMAND: Self = Status(127); pub const NO_SUCH_COMMAND: Self = Status(127);
/// The execution succeeded
pub const SUCCESS: Self = Status(0); pub const SUCCESS: Self = Status(0);
/// The process was killed
pub const TERMINATED: Self = Status(143); pub const TERMINATED: Self = Status(143);
/// In builtins that outputs bools, indicates that the result is true
pub const TRUE: Self = Status(0); 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)) } 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) } 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 { pub fn error<T: AsRef<str>>(err: T) -> Self {
let err = err.as_ref(); let err = err.as_ref();
if !err.is_empty() { if !err.is_empty() {
...@@ -23,6 +35,7 @@ impl Status { ...@@ -23,6 +35,7 @@ impl Status {
Status(1) Status(1)
} }
/// Wrong arguments submitted to the builtin
pub fn bad_argument<T: AsRef<str>>(err: T) -> Self { pub fn bad_argument<T: AsRef<str>>(err: T) -> Self {
let err = err.as_ref(); let err = err.as_ref();
if !err.is_empty() { if !err.is_empty() {
...@@ -31,12 +44,16 @@ impl Status { ...@@ -31,12 +44,16 @@ impl Status {
Status(2) Status(2)
} }
/// Indicates if the operation is successful
pub fn is_success(self) -> bool { self.0 == 0 } pub fn is_success(self) -> bool { self.0 == 0 }
/// Indicates if the operation is unsuccessful
pub fn is_failure(self) -> bool { self.0 != 0 } 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 } 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 }; } pub fn toggle(&mut self) { self.0 = if self.is_success() { 1 } else { 0 }; }
} }
......
use crate::types; 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 { pub fn check_help(args: &[types::Str], man_page: &'static str) -> bool {
for arg in args { for arg in args {
if arg == "-h" || arg == "--help" { if arg == "-h" || arg == "--help" {
......
/// helpers for creating help
pub mod man_pages; pub mod man_pages;
mod calc; mod calc;
...@@ -21,7 +22,7 @@ pub use self::{ ...@@ -21,7 +22,7 @@ pub use self::{
conditionals::{contains, ends_with, starts_with}, conditionals::{contains, ends_with, starts_with},
echo::builtin_echo, echo::builtin_echo,
exists::builtin_exists, exists::builtin_exists,
functions::print_functions, functions::builtin_fn_,
helpers::Status, helpers::Status,
is::builtin_is, is::builtin_is,
man_pages::check_help, man_pages::check_help,
...@@ -156,7 +157,7 @@ impl<'a> BuiltinMap<'a> { ...@@ -156,7 +157,7 @@ impl<'a> BuiltinMap<'a> {
/// ///
/// Contains `fn`, `alias`, `unalias`, `drop`, `read` /// Contains `fn`, `alias`, `unalias`, `drop`, `read`
pub fn with_variables(&mut self) -> &mut Self { 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("alias", &builtin_alias, "View, set or unset aliases")
.add("unalias", &builtin_unalias, "Delete an alias") .add("unalias", &builtin_unalias, "Delete an alias")
.add("drop", &builtin_drop, "Delete a variable") .add("drop", &builtin_drop, "Delete a variable")
...@@ -553,12 +554,6 @@ pub fn popd(args: &[types::Str], shell: &mut Shell<'_>) -> Status { ...@@ -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; struct EmptyCompleter;
impl Completer for EmptyCompleter { impl Completer for EmptyCompleter {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment