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};
|
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>> {
|
pub fn commands() -> Vec<Rc<Command>> {
|
||||||
let mut available_commands: Vec<Rc<Command>> = Vec::new();
|
let mut available_commands: Vec<Rc<Command>> = Vec::new();
|
||||||
|
|
||||||
@ -34,12 +42,7 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
"Prints the args".to_string(),
|
"Prints the args".to_string(),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|_console, args, _flags| {
|
|_console, args, _flags| {
|
||||||
let mut output = String::new();
|
Ok(Some(args.join(" ")))
|
||||||
for arg in args {
|
|
||||||
output.push_str(&format!("{} ", arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Some(output))
|
|
||||||
},
|
},
|
||||||
)));
|
)));
|
||||||
|
|
||||||
@ -53,6 +56,9 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
return Err("pwd does not take any arguments");
|
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()))
|
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!");
|
return Err("Only the path must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
match console.cd(args[0].clone()) {
|
match console.cd(args[0].clone(), None) {
|
||||||
Ok(_) => Ok(None),
|
Ok(_) => Ok(None),
|
||||||
Err(e) => Err(e),
|
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())),
|
Rc::new(super::Flag::new("list".to_string(), "l".to_string(), "Print contents in a list".to_string())),
|
||||||
],
|
],
|
||||||
|console, args, flags| {
|
|console, args, flags| {
|
||||||
if args.len() > 0 {
|
if args.len() > 1 {
|
||||||
return Err("ls does not take any arguments");
|
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" ) {
|
let seperator = match flags.iter().find(|f| f.long == "list" ) {
|
||||||
Some(_) => "\n",
|
Some(_) => "\n",
|
||||||
None => "\t",
|
None => "\t",
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut output = String::new();
|
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));
|
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));
|
output.push_str(&format!("{}{}", file.borrow().get_name(), seperator));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +126,15 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
Vec::new(),
|
Vec::new(),
|
||||||
|console, args, _flags| {
|
|console, args, _flags| {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return Err("Only the name must be specified!");
|
return Err("Only the path must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
|
||||||
// virtual_cd
|
Ok(dir) => dir,
|
||||||
// Get the directory name from the path
|
Err(e) => return Err(e),
|
||||||
|
};
|
||||||
|
|
||||||
let current_dir = console.get_current_dir();
|
let result = match dir.borrow_mut().mkdir(args[0].clone()) {
|
||||||
let result = match current_dir.borrow_mut().mkdir(args[0].clone()) {
|
|
||||||
Ok(_) => Ok(None),
|
Ok(_) => Ok(None),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
};
|
};
|
||||||
@ -138,15 +150,15 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
Vec::new(),
|
Vec::new(),
|
||||||
|console, args, _flags| {
|
|console, args, _flags| {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return Err("Only the name must be specified!");
|
return Err("Only the path must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
|
||||||
// virtual_cd
|
Ok(dir) => dir,
|
||||||
// Get the directory name from the path
|
Err(e) => return Err(e),
|
||||||
|
};
|
||||||
|
|
||||||
let current_dir = console.get_current_dir();
|
let result = match dir.borrow_mut().touch(args[0].clone()) {
|
||||||
let result = match current_dir.borrow_mut().touch(args[0].clone()) {
|
|
||||||
Ok(_) => Ok(None),
|
Ok(_) => Ok(None),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
};
|
};
|
||||||
@ -162,15 +174,15 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
Vec::new(),
|
Vec::new(),
|
||||||
|console, args, _flags| {
|
|console, args, _flags| {
|
||||||
if args.len() != 1 {
|
if args.len() != 1 {
|
||||||
return Err("Only the name must be specified!");
|
return Err("Only the file must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
|
||||||
// virtual_cd
|
Ok(dir) => dir,
|
||||||
// Get the directory name from the path
|
Err(e) => return Err(e),
|
||||||
|
};
|
||||||
|
|
||||||
let current_dir = console.get_current_dir();
|
let file = match dir.borrow().get_file(args[0].clone()) {
|
||||||
let file = match current_dir.borrow().get_file(args[0].clone()) {
|
|
||||||
Some(file) => file,
|
Some(file) => file,
|
||||||
None => return Err("File not found"),
|
None => return Err("File not found"),
|
||||||
};
|
};
|
||||||
@ -185,23 +197,32 @@ pub fn commands() -> Vec<Rc<Command>> {
|
|||||||
Rc::new(Command::new(
|
Rc::new(Command::new(
|
||||||
"rm".to_string(),
|
"rm".to_string(),
|
||||||
"Removes a file or directory".to_string(),
|
"Removes a file or directory".to_string(),
|
||||||
Vec::new(),
|
vec![
|
||||||
|console, args, _flags| {
|
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 {
|
if args.len() != 1 {
|
||||||
return Err("Only the name must be specified!");
|
return Err("Only the name must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
let dir = match console.virtual_cd(args[0].clone(), Some(1)) {
|
||||||
// virtual_cd
|
Ok(dir) => dir,
|
||||||
// Get the directory name from the path
|
Err(e) => return Err(e),
|
||||||
|
|
||||||
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),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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())),
|
Rc::new(super::Flag::new("append".to_string(), "a".to_string(), "Append to the file".to_string())),
|
||||||
],
|
],
|
||||||
|console, args, flags| {
|
|console, args, flags| {
|
||||||
// TODO
|
if args.len() < 2 {
|
||||||
// virtual_cd
|
return Err("Path and content must be specified!");
|
||||||
// Get the directory name from the path
|
}
|
||||||
|
|
||||||
let current_dir = console.get_current_dir();
|
log(format!("Args: {:?}", args).as_str());
|
||||||
let file = match current_dir.borrow().get_file(args[0].clone()) {
|
|
||||||
|
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,
|
Some(file) => file,
|
||||||
None => return Err("File not found"),
|
None => return Err("File not found"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if flags.iter().find(|f| f.long == "append" ).is_some() {
|
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);
|
return Ok(None);
|
||||||
} else {
|
} else {
|
||||||
file.borrow_mut().write(args[1].clone());
|
file.borrow_mut().write(args[1..].join(" "));
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,12 @@ use types::*;
|
|||||||
use commands::commands;
|
use commands::commands;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern "C" {
|
||||||
|
#[wasm_bindgen(js_namespace = console)]
|
||||||
|
fn log(s: &str);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Flag {
|
pub struct Flag {
|
||||||
pub long: String,
|
pub long: String,
|
||||||
pub short: 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 segments = PathSegment::parse_path_segment(path);
|
||||||
let mut current = self.get_current_dir();
|
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 {
|
for segment in segments {
|
||||||
|
if index >= break_index {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
match segment {
|
match segment {
|
||||||
PathSegment::Root => {
|
PathSegment::Root => {
|
||||||
self.pwd.borrow_mut().clear();
|
self.pwd.borrow_mut().clear();
|
||||||
@ -123,12 +141,22 @@ impl Console {
|
|||||||
|
|
||||||
// Function to get a directory from a path
|
// Function to get a directory from a path
|
||||||
// the PWD should be unchanged after this function
|
// 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> {
|
fn execute_inner(&mut self, command: String) -> Option<String> {
|
||||||
let mut args: Vec<String> = command.split(" ").map(|s| s.to_string()).collect();
|
let mut args: Vec<String> = command.split(" ").map(|s| s.to_string()).collect();
|
||||||
|
|
||||||
let command = match args.first() {
|
let command = match args.first() {
|
||||||
Some(command) => command,
|
Some(command) => command,
|
||||||
None => return Some("No command entered".to_string()),
|
None => return Some("No command entered".to_string()),
|
||||||
@ -156,7 +184,7 @@ impl Console {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl Console {
|
impl Console {
|
||||||
pub fn new() -> 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 {
|
let console = Console {
|
||||||
root,
|
root,
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
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 {
|
pub trait Content {
|
||||||
fn get_name(&self) -> String;
|
fn get_name(&self) -> String;
|
||||||
@ -7,7 +14,7 @@ pub trait Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct File {
|
pub struct File {
|
||||||
path: String,
|
parent_path: String,
|
||||||
name: String,
|
name: String,
|
||||||
content: String,
|
content: String,
|
||||||
}
|
}
|
||||||
@ -18,25 +25,29 @@ impl Content for File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_path(&self) -> String {
|
fn get_path(&self) -> String {
|
||||||
self.path.clone()
|
if self.parent_path == "/" {
|
||||||
|
format!("/{}", &self.name)
|
||||||
|
} else {
|
||||||
|
format!("{}/{}", &self.parent_path, &self.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl File {
|
impl File {
|
||||||
pub fn new(name: String, content: String, path: String) -> File {
|
pub fn new(name: String, content: String, parent_path: String) -> File {
|
||||||
File {
|
File {
|
||||||
name,
|
name,
|
||||||
content,
|
content,
|
||||||
path,
|
parent_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_new(name: String, path: String) -> File {
|
pub fn empty_new(name: String, parent_path: String) -> File {
|
||||||
File {
|
File {
|
||||||
name,
|
name,
|
||||||
content: String::new(),
|
content: String::new(),
|
||||||
path,
|
parent_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +72,7 @@ pub struct Directory {
|
|||||||
name: String,
|
name: String,
|
||||||
files: RefCell<Vec<Rc<RefCell<File>>>>,
|
files: RefCell<Vec<Rc<RefCell<File>>>>,
|
||||||
subdirs: RefCell<Vec<Rc<RefCell<Directory>>>>,
|
subdirs: RefCell<Vec<Rc<RefCell<Directory>>>>,
|
||||||
path: String,
|
pub parent_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Content for Directory {
|
impl Content for Directory {
|
||||||
@ -70,25 +81,25 @@ impl Content for Directory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_path(&self) -> String {
|
fn get_path(&self) -> String {
|
||||||
self.path.clone()
|
if self.parent_path == "/" {
|
||||||
|
format!("/{}", &self.name)
|
||||||
|
} else {
|
||||||
|
format!("{}/{}", &self.parent_path, &self.name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
impl Directory {
|
impl Directory {
|
||||||
pub fn new(name: String, path: String) -> Directory {
|
pub fn new(name: String, parent_path: String) -> Directory {
|
||||||
Directory {
|
Directory {
|
||||||
name,
|
name,
|
||||||
files: RefCell::new(Vec::new()),
|
files: RefCell::new(Vec::new()),
|
||||||
subdirs: 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>{
|
pub fn add_file(&mut self, file: File) -> Result<(), &'static str>{
|
||||||
if self.get_dir(file.name.clone()).is_some() {
|
if self.get_dir(file.name.clone()).is_some() {
|
||||||
return Err("File already exists");
|
return Err("File already exists");
|
||||||
@ -121,7 +132,7 @@ impl Directory {
|
|||||||
return Err("Directory name cannot contain spraces, '/' or '\\'");
|
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());
|
self.subdirs.borrow_mut().push(dir.clone());
|
||||||
Ok(dir)
|
Ok(dir)
|
||||||
}
|
}
|
||||||
@ -206,7 +217,7 @@ impl Directory {
|
|||||||
return Err("File name cannot contain spraces, '/' or '\\'");
|
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());
|
self.files.borrow_mut().push(file.clone());
|
||||||
Ok(file)
|
Ok(file)
|
||||||
}
|
}
|
||||||
@ -219,7 +230,7 @@ impl Directory {
|
|||||||
return Err("File name cannot contain spraces, '/' or '\\'");
|
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());
|
self.files.borrow_mut().push(file.clone());
|
||||||
Ok(file)
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user