diff options
| author | Fuwn <[email protected]> | 2021-05-16 12:23:18 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2021-05-16 12:23:18 +0000 |
| commit | e32b14b49709f9c64f24f25ce0ae1bf6c81d66b2 (patch) | |
| tree | cafebe133243dab9b7f1b16ad0b6c36de9386b7b /src | |
| parent | refactor(readme): linking, wording, and spacing (diff) | |
| download | whirl-e32b14b49709f9c64f24f25ce0ae1bf6c81d66b2.tar.xz whirl-e32b14b49709f9c64f24f25ce0ae1bf6c81d66b2.zip | |
feat(prompt): add a couple new builtins
`ls`, `cat`, and `config` builtins created.
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/mod.rs | 2 | ||||
| -rw-r--r-- | src/prompt/builtins.rs | 84 | ||||
| -rw-r--r-- | src/prompt/mod.rs | 20 | ||||
| -rw-r--r-- | src/subs.rs | 4 |
4 files changed, 99 insertions, 11 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs index ec94b57..8e6e053 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -44,6 +44,8 @@ pub struct Config { pub hub: HubConfig, } impl Config { + pub fn refresh() { let _ = config::Config::new().refresh(); } + fn load() -> Result<Self, ConfigError> { let mut s = config::Config::new(); diff --git a/src/prompt/builtins.rs b/src/prompt/builtins.rs index 27c0089..c3150e0 100644 --- a/src/prompt/builtins.rs +++ b/src/prompt/builtins.rs @@ -1,7 +1,11 @@ // Copyleft (ɔ) 2021-2021 The Whirlsplash Collective // SPDX-License-Identifier: GPL-3.0-only -use std::str::FromStr; +use std::{io::Write, str::FromStr}; + +use crate::config::Config; + +const FILES: [&str; 2] = ["README.rst", "Whirl.toml"]; pub enum BuiltIn { Echo, @@ -9,6 +13,9 @@ pub enum BuiltIn { Exit, Null, Help, + Ls, + Cat, + Config, } impl FromStr for BuiltIn { type Err = (); @@ -20,6 +27,9 @@ impl FromStr for BuiltIn { "exit" => Ok(BuiltIn::Exit), "null" => Ok(BuiltIn::Null), "help" => Ok(BuiltIn::Help), + "ls" => Ok(BuiltIn::Ls), + "cat" => Ok(BuiltIn::Cat), + "config" => Ok(BuiltIn::Config), _ => Err(()), } } @@ -38,9 +48,73 @@ pub fn builtin_history(history: Vec<String>) -> i32 { } pub fn builtin_help() -> i32 { - println!( - "echo - display a line of text\nhistory - manipulate the history list\nexit - end the \ - application" - ); + println!("echo - display a line of predefined text"); + println!("history - display the command history"); + println!("exit - end the process"); + println!("ls - display the present files"); + println!("cat - display the contents of a present file"); + println!("config - manipulate the configuration"); + println!("help - you are here"); + 0 +} + +pub fn builtin_ls() -> i32 { + for file in &FILES { + print!("{} ", file); + } + println!(); + + 0 +} + +pub async fn builtin_cat(args: &[String]) -> i32 { + let file; + if let Some(file_name) = args.get(0) { + file = file_name.to_string(); + } else { + return 0; + }; + + match file.as_str() { + "README.rst" => { + let mut easy = curl::easy::Easy::new(); + + easy + .url("https://raw.githubusercontent.com/Whirlsplash/whirl/develop/README.rst") + .unwrap(); + + let mut transfer = easy.transfer(); + transfer + .write_function(|data| { + std::io::stdout().write_all(data).unwrap(); + Ok(data.len()) + }) + .unwrap(); + transfer.perform().unwrap(); + } + "Whirl.toml" => { + println!("{:#?}", Config::get()); + } + _ => println!("/cat: {}: no such file or directory", file), + } + + 0 +} + +pub fn builtin_config(args: &[String]) -> i32 { + match args.get(0) { + Some(sub) => + match sub.as_str() { + "show" => println!("{:#?}", Config::get()), + "help" | "--help" | "-h" => { + println!("show - display the current configuration"); + println!("help - you are here"); + println!("refresh - reload the configuration file"); + } + "refresh" => Config::refresh(), + _ => println!("invalid arguments provided"), + }, + None => println!("invalid amount arguments provided"), + } 0 } diff --git a/src/prompt/mod.rs b/src/prompt/mod.rs index 9a94a44..3deb4fe 100644 --- a/src/prompt/mod.rs +++ b/src/prompt/mod.rs @@ -9,7 +9,15 @@ use std::{io, io::Write, str::FromStr}; use crate::{ config::Config, prompt::{ - builtins::{builtin_echo, builtin_help, builtin_history, BuiltIn}, + builtins::{ + builtin_cat, + builtin_config, + builtin_echo, + builtin_help, + builtin_history, + builtin_ls, + BuiltIn, + }, structure::Command, }, }; @@ -18,7 +26,7 @@ pub struct Prompt { history: Vec<String>, } impl Prompt { - pub fn handle() -> ! { + pub async fn handle() -> ! { let mut prompt = Prompt { history: vec![] }; @@ -28,7 +36,8 @@ impl Prompt { Prompt::process_command( Prompt::tokenize_command(prompt.read_command()), prompt.history.clone(), - ); + ) + .await; } } @@ -63,13 +72,16 @@ impl Prompt { // TODO: Find a way to make this access itself `history` doesn't have to be // passed everytime. - fn process_command(c: Command, history: Vec<String>) -> i32 { + async fn process_command(c: Command, history: Vec<String>) -> i32 { match BuiltIn::from_str(&c.keyword) { Ok(BuiltIn::Echo) => builtin_echo(&c.args), Ok(BuiltIn::Exit) => std::process::exit(0), Ok(BuiltIn::History) => builtin_history(history), Ok(BuiltIn::Null) => 0, Ok(BuiltIn::Help) => builtin_help(), + Ok(BuiltIn::Ls) => builtin_ls(), + Ok(BuiltIn::Cat) => builtin_cat(&c.args).await, + Ok(BuiltIn::Config) => builtin_config(&c.args), _ => { println!("wsh: command not found: {}", &c.keyword); 1 diff --git a/src/subs.rs b/src/subs.rs index 5ecf9bd..1066c3f 100644 --- a/src/subs.rs +++ b/src/subs.rs @@ -13,7 +13,7 @@ use crate::{ }, }; -pub async fn run() -> ! { +pub async fn run() { let (tx, _rx) = std::sync::mpsc::channel(); let _threads = vec![ @@ -45,7 +45,7 @@ pub async fn run() -> ! { } } else { std::thread::sleep(std::time::Duration::from_secs(2)); - Prompt::handle(); + Prompt::handle().await; } // actix_web::rt::System::new("").block_on(rx.recv().unwrap().stop(true)); |