From f5a27156d2ea44f60581f6e879443252bd334559 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 14 Aug 2024 08:47:29 -0700 Subject: [PATCH] [Teton] Add ls and cd commands to rust impl. --- rust/lib/victoriafalls/src/dir.rs | 27 +++++++++++++++++++++++++++ rust/lib/victoriafalls/src/file.rs | 20 +------------------- rust/lib/victoriafalls/src/lib.rs | 18 ++++++++++++++++++ rust/sys/teton/src/terminal.rs | 26 +++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 rust/lib/victoriafalls/src/dir.rs diff --git a/rust/lib/victoriafalls/src/dir.rs b/rust/lib/victoriafalls/src/dir.rs new file mode 100644 index 0000000..fb6efeb --- /dev/null +++ b/rust/lib/victoriafalls/src/dir.rs @@ -0,0 +1,27 @@ +use alloc::{ + string::{String, ToString as _}, + vec::Vec, +}; +use mammoth::zion::ZError; + +pub fn exists(path: &str) -> Result { + let vfs = crate::get_client(); + let result = vfs.get_directory(&crate::GetDirectoryRequest { + path: path.to_string(), + }); + + match result { + Ok(_) => Ok(true), + Err(ZError::NOT_FOUND) => Ok(false), + Err(e) => Err(e), + } +} + +pub fn ls(path: &str) -> Result, ZError> { + let vfs = crate::get_client(); + let result = vfs.get_directory(&crate::GetDirectoryRequest { + path: path.to_string(), + })?; + + Ok(result.filenames.split(',').map(|s| s.to_string()).collect()) +} diff --git a/rust/lib/victoriafalls/src/file.rs b/rust/lib/victoriafalls/src/file.rs index ec6b190..2f37990 100644 --- a/rust/lib/victoriafalls/src/file.rs +++ b/rust/lib/victoriafalls/src/file.rs @@ -1,32 +1,14 @@ use crate::OpenFileRequest; -use crate::VFSClient; use alloc::string::ToString; use mammoth::zion::ZError; -static mut VFS_CLIENT: Option = None; - -fn get_client() -> &'static mut VFSClient { - unsafe { - if let None = VFS_CLIENT { - let endpoint_cap = yellowstone::from_init_endpoint() - .get_endpoint(&yellowstone::GetEndpointRequest { - endpoint_name: "victoriafalls".to_string(), - }) - .expect("Failed to get VFS endpoint"); - - VFS_CLIENT = Some(VFSClient::new(endpoint_cap.endpoint)); - } - VFS_CLIENT.as_mut().unwrap() - } -} - pub struct File { memory: mammoth::mem::MemoryRegion, } impl File { pub fn open(path: &str) -> Result { - let vfs = get_client(); + let vfs = crate::get_client(); let resp = vfs.open_file(&OpenFileRequest { path: path.to_string(), })?; diff --git a/rust/lib/victoriafalls/src/lib.rs b/rust/lib/victoriafalls/src/lib.rs index e35a8ef..b1532a9 100644 --- a/rust/lib/victoriafalls/src/lib.rs +++ b/rust/lib/victoriafalls/src/lib.rs @@ -4,4 +4,22 @@ use core::include; include!(concat!(env!("OUT_DIR"), "/yunq.rs")); +pub mod dir; pub mod file; + +static mut VFS_CLIENT: Option = None; + +fn get_client() -> &'static mut VFSClient { + unsafe { + if let None = VFS_CLIENT { + let endpoint_cap = yellowstone::from_init_endpoint() + .get_endpoint(&yellowstone::GetEndpointRequest { + endpoint_name: "victoriafalls".to_string(), + }) + .expect("Failed to get VFS endpoint"); + + VFS_CLIENT = Some(VFSClient::new(endpoint_cap.endpoint)); + } + VFS_CLIENT.as_mut().unwrap() + } +} diff --git a/rust/sys/teton/src/terminal.rs b/rust/sys/teton/src/terminal.rs index 1823de7..4ecdc28 100644 --- a/rust/sys/teton/src/terminal.rs +++ b/rust/sys/teton/src/terminal.rs @@ -5,6 +5,7 @@ use alloc::{ format, string::{String, ToString}, }; +use victoriafalls::dir; use voyageurs::listener::KeyboardHandler; pub struct Terminal { @@ -84,10 +85,33 @@ impl Terminal { self.curr_cmd.clear() } - fn execute_command_parsed(&mut self, cmd: &str, _args: Split<'_, char>) { + fn execute_command_parsed(&mut self, cmd: &str, mut args: Split<'_, char>) { + // TODO: Check that no extraneous params are provided. match cmd { "help" => self.write_line("Available commands are 'pwd', 'ls', 'cd', and 'exec'"), "pwd" => self.write_line(&self.cwd.clone()), + "cd" => match args.next() { + None => self.write_line("Specify a directory"), + Some(directory) => match dir::exists(directory) { + Ok(true) => self.cwd = directory.to_string(), + Ok(false) => self.write_line(&format!("Directory not found: {}", directory)), + Err(e) => self.write_line(&format!("Error stating directory {:?}", e)), + }, + }, + "ls" => { + let use_dir = match args.next() { + None => self.cwd.clone(), + Some(d) => d.to_string(), + }; + match dir::ls(&use_dir) { + Err(e) => self.write_line(&format!("Error reading directory {:?}", e)), + Ok(files) => { + for file in files { + self.write_line(&file); + } + } + } + } _ => self.write_line(&format!("Unrecognized command: {}", cmd)), } }