From 0a0dfc2ee9f7005889bb87cb8356da1ab7843377 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sat, 18 Mar 2023 11:51:42 -0500 Subject: [PATCH] reorganizing extension commands --- src/ext.rs | 5 ++++ src/ext/command.rs | 7 ++++++ src/ext/tail.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 17 ++++++++------ src/output.rs | 30 +++++++++++++----------- src/shell.rs | 38 +++--------------------------- 6 files changed, 99 insertions(+), 56 deletions(-) create mode 100644 src/ext.rs create mode 100644 src/ext/command.rs create mode 100644 src/ext/tail.rs diff --git a/src/ext.rs b/src/ext.rs new file mode 100644 index 0000000..762d05a --- /dev/null +++ b/src/ext.rs @@ -0,0 +1,5 @@ +mod tail; +mod command; + +pub use tail::Tail; +pub use command::Command; diff --git a/src/ext/command.rs b/src/ext/command.rs new file mode 100644 index 0000000..2fcbb3d --- /dev/null +++ b/src/ext/command.rs @@ -0,0 +1,7 @@ +pub trait Command { + fn name() -> String; + + fn create() -> Self; + + fn exec(&mut self, args: Vec<&str>) -> anyhow::Result; +} diff --git a/src/ext/tail.rs b/src/ext/tail.rs new file mode 100644 index 0000000..03b0b44 --- /dev/null +++ b/src/ext/tail.rs @@ -0,0 +1,58 @@ +use crate::{ + ext::Command, + output, +}; + +use std::{ + fs::File, + io::{Seek, SeekFrom, Read, Write}, +}; + +use anyhow::Result; + +pub struct Tail { } + +impl Command for Tail { + fn name() -> String { + String::from("tail") + } + + fn create() -> Self { + Self{ } + } + + fn exec(&mut self, args: Vec<&str>) -> Result { + let mut stdout = output::Writer::stdout()?; + if args.len() > 0 { + let fname = args[0]; + match File::options().read(true).open(fname) { + Ok(mut f) => { + _ = f.seek(SeekFrom::End(0)); + let mut one_byte: [u8; 1] = [0; 1]; + let mut buf: Vec = vec![]; + loop { + match f.read(&mut one_byte) { + Ok(n) => { + if n == 1 { + buf.push(one_byte[0]); + if let Ok(s) = std::str::from_utf8(&buf) { + stdout.write(s.as_bytes())?; + buf.clear(); + } + } + } + Err(_) => {} + } + } + } + Err(e) => { + println!("failed to open file: {}", e); + return Err(e.into()); + } + } + } else { + println!("need a file name"); + return Ok(false); + } + } +} diff --git a/src/main.rs b/src/main.rs index b2571a0..146def2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,21 @@ mod error; +mod ext; mod input; mod key; mod line; mod log; mod output; -mod shell; mod prompt; +mod shell; +use crate::log::*; use prompt::Prompt; +use shell::Shell; + use std::io::Write; use anyhow::Result; -use crate::log::*; -use shell::Shell; - fn main() -> Result<()> { let mut shell = Shell::new()?; let log_path = shell.expand_path("~/wash.log"); @@ -99,7 +100,7 @@ fn main() -> Result<()> { // the tail if n > 1 { // let text = format!("\x1b[{}D", n - 1); - shell.output.back(n-1)?; + shell.output.back(n - 1)?; // output.write(text.as_bytes())?; } else { // honestly I can't remember how I figured this out @@ -120,7 +121,9 @@ fn main() -> Result<()> { if event.ctrl && event.code == key::J { debug!("⎈ j: dot"); // red bullet - shell.output.write(String::from("\x1b[31m\u{2022}\x1b[0m").as_bytes())?; + shell + .output + .write(String::from("\x1b[31m\u{2022}\x1b[0m").as_bytes())?; continue; } @@ -177,7 +180,7 @@ fn main() -> Result<()> { if n > 1 { // if we wrote more than one character, because we weren't at the end, we // need to rewind the terminal cursor to where it was. - shell.output.back(n-1)?; + shell.output.back(n - 1)?; } continue; } diff --git a/src/output.rs b/src/output.rs index a007860..ef880fe 100644 --- a/src/output.rs +++ b/src/output.rs @@ -94,27 +94,29 @@ fn log_output_mode(mode: Console::CONSOLE_MODE) { } } -fn stdout_handle() -> Result { - unsafe { - let handle = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE) - .context("unable to get stdin handle")?; - Ok(handle) - } -} - pub struct Writer { output: HANDLE, } impl Writer { - pub fn new() -> Result { - let mut v = Self { - output: stdout_handle()?, - }; - v.reset()?; - Ok(v) + pub fn stdout() -> Result { + unsafe { + let handle = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE) + .context("unable to get stdin handle")?; + let mut stdout = Self{output: handle}; + stdout.reset()?; + Ok(stdout) + } } + // pub fn new() -> Result { + // let mut v = Self { + // output: stdout_handle()?, + // }; + // v.reset()?; + // Ok(v) + // } + pub fn close(&mut self) -> Result<()> { unsafe { CloseHandle(self.output); diff --git a/src/shell.rs b/src/shell.rs index cd24758..af9b1a4 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,4 +1,4 @@ -use crate::{input, line::Line, log::*, output}; +use crate::{input, line::Line, log::*, output, ext::{Command, Tail}}; use std::{ fs::File, @@ -19,7 +19,7 @@ impl Shell { pub fn new() -> Result { Ok(Self { input: input::Reader::new()?, - output: output::Writer::new()?, + output: output::Writer::stdout()?, line: Line::new(), }) } @@ -145,39 +145,7 @@ impl Shell { return Ok(false); } } - "tail" => { - if args.len() > 0 { - let fname = args[0]; - match File::options().read(true).open(fname) { - Ok(mut f) => { - _ = f.seek(SeekFrom::End(0)); - let mut one_byte: [u8; 1] = [0; 1]; - let mut buf: Vec = vec![]; - loop { - match f.read(&mut one_byte) { - Ok(n) => { - if n == 1 { - buf.push(one_byte[0]); - if let Ok(s) = std::str::from_utf8(&buf) { - self.output.write(s.as_bytes())?; - buf.clear(); - } - } - } - Err(_) => {} - } - } - } - Err(e) => { - println!("failed to open file: {}", e); - return Err(e.into()); - } - } - } else { - println!("need a file name"); - return Ok(false); - } - } + "tail" => Tail::create().exec(args), "echo" => { println!("{}", args.join(" ")); return Ok(true);