So... a lot more works now

This commit is contained in:
Daniel Kluge 2024-01-03 12:29:39 +01:00
parent a5e3039f80
commit 798582ae7d
3 changed files with 138 additions and 72 deletions

View File

@ -2,6 +2,14 @@ use std::rc::Rc;
use super::{Command, types::Content};
// TODO: Remove this
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
pub fn commands() -> Vec<Rc<Command>> {
let mut available_commands: Vec<Rc<Command>> = Vec::new();
@ -34,12 +42,7 @@ pub fn commands() -> Vec<Rc<Command>> {
"Prints the args".to_string(),
Vec::new(),
|_console, args, _flags| {
let mut output = String::new();
for arg in args {
output.push_str(&format!("{} ", arg));
}
Ok(Some(output))
Ok(Some(args.join(" ")))
},
)));
@ -53,6 +56,9 @@ pub fn commands() -> Vec<Rc<Command>> {
return Err("pwd does not take any arguments");
}
log(console.get_current_dir().borrow().get_name().as_str());
log(console.get_current_dir().borrow().get_path().as_str());
Ok(Some(console.get_current_dir().borrow().get_path()))
},
)));
@ -67,7 +73,7 @@ pub fn commands() -> Vec<Rc<Command>> {
return Err("Only the path must be specified!");
}
match console.cd(args[0].clone()) {
match console.cd(args[0].clone(), None) {
Ok(_) => Ok(None),
Err(e) => Err(e),
}
@ -82,24 +88,30 @@ pub fn commands() -> Vec<Rc<Command>> {
Rc::new(super::Flag::new("list".to_string(), "l".to_string(), "Print contents in a list".to_string())),
],
|console, args, flags| {
if args.len() > 0 {
return Err("ls does not take any arguments");
if args.len() > 1 {
return Err("ls does not take any arguments but a path");
}
// TODO
// Virtual cd to read the contents there
let seperator = match flags.iter().find(|f| f.long == "list" ) {
Some(_) => "\n",
None => "\t",
};
let mut output = String::new();
let current_dir = console.get_current_dir();
for dir in current_dir.borrow().get_subdirs() {
let base = if args.len() == 0 {
console.get_current_dir()
} else {
match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
}
};
for dir in base.borrow().get_subdirs() {
output.push_str(&format!("{}{}", dir.borrow().get_name(), seperator));
}
for file in current_dir.borrow().get_files() {
for file in base.borrow().get_files() {
output.push_str(&format!("{}{}", file.borrow().get_name(), seperator));
}
@ -114,15 +126,15 @@ pub fn commands() -> Vec<Rc<Command>> {
Vec::new(),
|console, args, _flags| {
if args.len() != 1 {
return Err("Only the name must be specified!");
return Err("Only the path must be specified!");
}
// TODO
// virtual_cd
// Get the directory name from the path
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
};
let current_dir = console.get_current_dir();
let result = match current_dir.borrow_mut().mkdir(args[0].clone()) {
let result = match dir.borrow_mut().mkdir(args[0].clone()) {
Ok(_) => Ok(None),
Err(e) => Err(e),
};
@ -138,15 +150,15 @@ pub fn commands() -> Vec<Rc<Command>> {
Vec::new(),
|console, args, _flags| {
if args.len() != 1 {
return Err("Only the name must be specified!");
return Err("Only the path must be specified!");
}
// TODO
// virtual_cd
// Get the directory name from the path
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
};
let current_dir = console.get_current_dir();
let result = match current_dir.borrow_mut().touch(args[0].clone()) {
let result = match dir.borrow_mut().touch(args[0].clone()) {
Ok(_) => Ok(None),
Err(e) => Err(e),
};
@ -162,15 +174,15 @@ pub fn commands() -> Vec<Rc<Command>> {
Vec::new(),
|console, args, _flags| {
if args.len() != 1 {
return Err("Only the name must be specified!");
return Err("Only the file must be specified!");
}
// TODO
// virtual_cd
// Get the directory name from the path
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
};
let current_dir = console.get_current_dir();
let file = match current_dir.borrow().get_file(args[0].clone()) {
let file = match dir.borrow().get_file(args[0].clone()) {
Some(file) => file,
None => return Err("File not found"),
};
@ -185,23 +197,32 @@ pub fn commands() -> Vec<Rc<Command>> {
Rc::new(Command::new(
"rm".to_string(),
"Removes a file or directory".to_string(),
Vec::new(),
|console, args, _flags| {
vec![
Rc::new(super::Flag::new("recursive".to_string(), "r".to_string(), "Remove directories and their contents recursively".to_string())),
],
|console, args, flags| {
if args.len() != 1 {
return Err("Only the name must be specified!");
}
// TODO
// virtual_cd
// Get the directory name from the path
let current_dir = console.get_current_dir();
let result = match current_dir.borrow_mut().remove_file(args[0].clone()) {
Ok(_) => Ok(None),
Err(e) => Err(e),
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
};
result
_ = match dir.borrow_mut().remove_file(args[0].clone()) {
Ok(_) => return Ok(None),
Err(_) => "",
};
if flags.iter().find(|f| f.long == "recursive" ).is_some() {
match dir.borrow_mut().remove_dir(args[0].clone()) {
Ok(_) => return Ok(None),
Err(e) => return Err(e),
};
} else {
return Err("File could not be found!");
}
},
)));
@ -214,21 +235,27 @@ pub fn commands() -> Vec<Rc<Command>> {
Rc::new(super::Flag::new("append".to_string(), "a".to_string(), "Append to the file".to_string())),
],
|console, args, flags| {
// TODO
// virtual_cd
// Get the directory name from the path
if args.len() < 2 {
return Err("Path and content must be specified!");
}
let current_dir = console.get_current_dir();
let file = match current_dir.borrow().get_file(args[0].clone()) {
log(format!("Args: {:?}", args).as_str());
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
Ok(dir) => dir,
Err(e) => return Err(e),
};
let file = match dir.borrow().get_file(args[0].clone()) {
Some(file) => file,
None => return Err("File not found"),
};
if flags.iter().find(|f| f.long == "append" ).is_some() {
file.borrow_mut().append(args[1].clone());
file.borrow_mut().append(args[1..].join(" "));
return Ok(None);
} else {
file.borrow_mut().write(args[1].clone());
file.borrow_mut().write(args[1..].join(" "));
Ok(None)
}

View File

@ -6,6 +6,12 @@ use types::*;
use commands::commands;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
pub struct Flag {
pub long: String,
pub short: String,
@ -88,11 +94,23 @@ impl Console {
}
}
fn cd(&mut self, path: String) -> Result<(), &'static str> {
fn cd(&mut self, path: String, skip_last_n: Option<usize>) -> Result<(), &'static str> {
let segments = PathSegment::parse_path_segment(path);
let mut current = self.get_current_dir();
let mut index = 0;
let break_index = match skip_last_n {
Some(n) => segments.len() - n as usize,
None => segments.len(),
};
for segment in segments {
if index >= break_index {
break;
} else {
index += 1;
}
match segment {
PathSegment::Root => {
self.pwd.borrow_mut().clear();
@ -123,12 +141,22 @@ impl Console {
// Function to get a directory from a path
// the PWD should be unchanged after this function
/*fn virtual_cd(&self, path: String) -> Result<Box<&mut Directory>, &'static str> {
fn virtual_cd(&mut self, path: String, skip_last_n: Option<usize>) -> Result<Rc<RefCell<Directory>>, &'static str> {
let pwd = self.pwd.borrow().clone();
}*/
match self.cd(path, skip_last_n) {
Ok(_) => (),
Err(e) => return Err(e),
};
let result = self.get_current_dir();
self.pwd.replace(pwd);
Ok(result)
}
fn execute_inner(&mut self, command: String) -> Option<String> {
let mut args: Vec<String> = command.split(" ").map(|s| s.to_string()).collect();
let command = match args.first() {
Some(command) => command,
None => return Some("No command entered".to_string()),
@ -156,7 +184,7 @@ impl Console {
#[wasm_bindgen]
impl Console {
pub fn new() -> Console {
let root = Rc::new(RefCell::new(Directory::new("".to_string(), "/".to_string())));
let root = Rc::new(RefCell::new(Directory::new("".to_string(), "".to_string())));
let console = Console {
root,

View File

@ -1,5 +1,12 @@
use std::{cell::RefCell, rc::Rc};
// TODO: Remove this
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
pub trait Content {
fn get_name(&self) -> String;
@ -7,7 +14,7 @@ pub trait Content {
}
pub struct File {
path: String,
parent_path: String,
name: String,
content: String,
}
@ -18,25 +25,29 @@ impl Content for File {
}
fn get_path(&self) -> String {
self.path.clone()
if self.parent_path == "/" {
format!("/{}", &self.name)
} else {
format!("{}/{}", &self.parent_path, &self.name)
}
}
}
#[allow(unused)]
impl File {
pub fn new(name: String, content: String, path: String) -> File {
pub fn new(name: String, content: String, parent_path: String) -> File {
File {
name,
content,
path,
parent_path,
}
}
pub fn empty_new(name: String, path: String) -> File {
pub fn empty_new(name: String, parent_path: String) -> File {
File {
name,
content: String::new(),
path,
parent_path,
}
}
@ -61,7 +72,7 @@ pub struct Directory {
name: String,
files: RefCell<Vec<Rc<RefCell<File>>>>,
subdirs: RefCell<Vec<Rc<RefCell<Directory>>>>,
path: String,
pub parent_path: String,
}
impl Content for Directory {
@ -70,25 +81,25 @@ impl Content for Directory {
}
fn get_path(&self) -> String {
self.path.clone()
if self.parent_path == "/" {
format!("/{}", &self.name)
} else {
format!("{}/{}", &self.parent_path, &self.name)
}
}
}
#[allow(unused)]
impl Directory {
pub fn new(name: String, path: String) -> Directory {
pub fn new(name: String, parent_path: String) -> Directory {
Directory {
name,
files: RefCell::new(Vec::new()),
subdirs: RefCell::new(Vec::new()),
path,
parent_path,
}
}
pub fn path(&self) -> String {
self.path.clone() + "/" + &self.name
}
pub fn add_file(&mut self, file: File) -> Result<(), &'static str>{
if self.get_dir(file.name.clone()).is_some() {
return Err("File already exists");
@ -121,7 +132,7 @@ impl Directory {
return Err("Directory name cannot contain spraces, '/' or '\\'");
}
let dir = Rc::new(RefCell::new(Directory::new(name, self.path())));
let dir = Rc::new(RefCell::new(Directory::new(name, self.get_path())));
self.subdirs.borrow_mut().push(dir.clone());
Ok(dir)
}
@ -206,7 +217,7 @@ impl Directory {
return Err("File name cannot contain spraces, '/' or '\\'");
}
let file = Rc::new(RefCell::new(File::empty_new(name, self.path.clone())));
let file = Rc::new(RefCell::new(File::empty_new(name, self.get_path())));
self.files.borrow_mut().push(file.clone());
Ok(file)
}
@ -219,7 +230,7 @@ impl Directory {
return Err("File name cannot contain spraces, '/' or '\\'");
}
let file = Rc::new(RefCell::new(File::new(name, content, self.path())));
let file = Rc::new(RefCell::new(File::new(name, content, self.get_path())));
self.files.borrow_mut().push(file.clone());
Ok(file)
}