So... a lot more works now
This commit is contained in:
parent
a5e3039f80
commit
798582ae7d
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user