diff --git a/src/commands.rs b/src/commands.rs index 55731b6079..e7550af4e6 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -3,6 +3,7 @@ crate mod cd; crate mod command; crate mod ls; crate mod ps; +crate mod reject; crate mod select; crate mod take; crate mod to_array; diff --git a/src/commands/cd.rs b/src/commands/cd.rs index 1199d76563..265d347c04 100644 --- a/src/commands/cd.rs +++ b/src/commands/cd.rs @@ -1,6 +1,6 @@ use crate::errors::ShellError; use crate::object::process::Process; -use crate::object::{DirEntry, ShellObject, Value}; +use crate::object::{dir_entry_dict, ShellObject, Value}; use crate::prelude::*; use crate::Args; use derive_new::new; diff --git a/src/commands/ls.rs b/src/commands/ls.rs index 4941463b04..bd6fc7f617 100644 --- a/src/commands/ls.rs +++ b/src/commands/ls.rs @@ -1,6 +1,6 @@ use crate::errors::ShellError; use crate::object::process::Process; -use crate::object::{DirEntry, ShellObject, Value}; +use crate::object::{dir_entry_dict, ShellObject, Value}; use crate::prelude::*; use crate::Args; use crate::Command; @@ -37,7 +37,7 @@ impl crate::Command for Ls { let mut shell_entries = VecDeque::new(); for entry in entries { - let value = Value::object(DirEntry::new(entry?)?); + let value = Value::Object(dir_entry_dict(&entry?)?); shell_entries.push_back(ReturnValue::Value(value)) } diff --git a/src/commands/ps.rs b/src/commands/ps.rs index 58c06c66be..17fe91bc9f 100644 --- a/src/commands/ps.rs +++ b/src/commands/ps.rs @@ -1,5 +1,5 @@ use crate::errors::ShellError; -use crate::object::process::Process; +use crate::object::process::process_dict; use crate::object::{ShellObject, Value}; use crate::prelude::*; use crate::Command; @@ -34,9 +34,7 @@ impl crate::Command for Ps { let list = list .into_iter() - .map(|(_, process)| { - ReturnValue::Value(Value::Object(Box::new(Process::new(process.clone())))) - }) + .map(|(_, process)| ReturnValue::Value(Value::Object(process_dict(process)))) .collect::>(); Ok(list) diff --git a/src/commands/reject.rs b/src/commands/reject.rs new file mode 100644 index 0000000000..fb4c45b20a --- /dev/null +++ b/src/commands/reject.rs @@ -0,0 +1,46 @@ +use crate::errors::ShellError; +use crate::object::base::reject; +use crate::object::process::Process; +use crate::object::{dir_entry_dict, ShellObject, Value}; +use crate::prelude::*; +use crate::Args; +use derive_new::new; +use std::path::{Path, PathBuf}; +use sysinfo::SystemExt; + +#[derive(new)] +pub struct RejectBlueprint; + +impl crate::CommandBlueprint for RejectBlueprint { + fn create( + &self, + args: Vec, + host: &dyn Host, + env: &mut Environment, + ) -> Result, ShellError> { + if args.is_empty() { + return Err(ShellError::string("take requires an integer")); + } + + let fields: Result<_, _> = args.iter().map(|a| a.as_string()).collect(); + + Ok(Box::new(Reject { fields: fields? })) + } +} + +#[derive(new)] +pub struct Reject { + fields: Vec, +} + +impl crate::Command for Reject { + fn run(&mut self, stream: VecDeque) -> Result, ShellError> { + let objects = stream + .iter() + .map(|item| Value::Object(reject(item, &self.fields))) + .map(|item| ReturnValue::Value(item)) + .collect(); + + Ok(objects) + } +} diff --git a/src/commands/select.rs b/src/commands/select.rs index 4c325825ad..325b857875 100644 --- a/src/commands/select.rs +++ b/src/commands/select.rs @@ -1,7 +1,7 @@ use crate::errors::ShellError; use crate::object::base::select; use crate::object::process::Process; -use crate::object::{DirEntry, ShellObject, Value}; +use crate::object::{dir_entry_dict, ShellObject, Value}; use crate::prelude::*; use crate::Args; use derive_new::new; @@ -37,7 +37,7 @@ impl crate::Command for Select { fn run(&mut self, stream: VecDeque) -> Result, ShellError> { let objects = stream .iter() - .map(|item| Value::Object(Box::new(select(item, &self.fields)))) + .map(|item| Value::Object(select(item, &self.fields))) .map(|item| ReturnValue::Value(item)) .collect(); diff --git a/src/commands/take.rs b/src/commands/take.rs index 669b37e323..017c9609e0 100644 --- a/src/commands/take.rs +++ b/src/commands/take.rs @@ -1,6 +1,6 @@ use crate::errors::ShellError; use crate::object::process::Process; -use crate::object::{DirEntry, ShellObject, Value}; +use crate::object::{dir_entry_dict, ShellObject, Value}; use crate::prelude::*; use crate::Args; use derive_new::new; diff --git a/src/commands/to_array.rs b/src/commands/to_array.rs index e2c9f2de8c..d56461f64e 100644 --- a/src/commands/to_array.rs +++ b/src/commands/to_array.rs @@ -1,6 +1,6 @@ use crate::errors::ShellError; use crate::object::process::Process; -use crate::object::{DirEntry, ShellObject, Value}; +use crate::object::{dir_entry_dict, ShellObject, Value}; use crate::prelude::*; use crate::Args; use derive_new::new; diff --git a/src/main.rs b/src/main.rs index 83bf804228..5c1bf3630a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,6 +67,7 @@ fn main() -> Result<(), Box> { ("cd", Box::new(cd::CdBlueprint)), ("take", Box::new(take::TakeBlueprint)), ("select", Box::new(select::SelectBlueprint)), + ("reject", Box::new(reject::RejectBlueprint)), ("to-array", Box::new(to_array::ToArrayBlueprint)), ]); } diff --git a/src/object.rs b/src/object.rs index dd56efb61c..6dea6ec880 100644 --- a/src/object.rs +++ b/src/object.rs @@ -8,4 +8,4 @@ crate mod types; crate use base::{Primitive, ShellObject, Value}; crate use desc::{DataDescriptor, DataDescriptorInstance}; crate use dict::Dictionary; -crate use files::DirEntry; +crate use files::dir_entry_dict; diff --git a/src/object/base.rs b/src/object/base.rs index 017ea2659e..a81606a6b1 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -51,7 +51,7 @@ impl Primitive { #[derive(Debug)] pub enum Value { Primitive(Primitive), - Object(Box), + Object(crate::object::Dictionary), List(Vec), Error(Box), } @@ -87,7 +87,7 @@ impl ShellObject for Value { fn copy(&self) -> Value { match self { Value::Primitive(p) => Value::Primitive(p.clone()), - Value::Object(o) => Value::Object(Box::new(o.copy())), + Value::Object(o) => Value::Object(o.copy_dict()), Value::List(l) => { let list = l.iter().map(|i| i.copy()).collect(); Value::List(list) @@ -179,10 +179,6 @@ impl Value { crate fn list(values: impl Into>) -> Value { Value::List(values.into()) } - - crate fn object(value: impl ShellObject + 'static) -> Value { - Value::Object(Box::new(value)) - } } pub trait ShellObject: Debug { @@ -207,6 +203,22 @@ crate fn select(obj: impl ShellObject, fields: &[String]) -> crate::object::Dict out } +crate fn reject(obj: impl ShellObject, fields: &[String]) -> crate::object::Dictionary { + let mut out = crate::object::Dictionary::default(); + + let descs = obj.data_descriptors(); + + for desc in descs { + if fields.contains(&desc.name) { + continue; + } else { + out.add(desc.name.clone(), obj.get_data(&desc).borrow().copy()) + } + } + + out +} + pub trait ToEntriesView { fn to_entries_view(&self) -> EntriesView; } diff --git a/src/object/dict.rs b/src/object/dict.rs index 050b63997b..c135ec7ddc 100644 --- a/src/object/dict.rs +++ b/src/object/dict.rs @@ -50,6 +50,6 @@ impl crate::object::ShellObject for Dictionary { } fn copy(&self) -> Value { - Value::Object(Box::new(self.copy_dict())) + Value::Object(self.copy_dict()) } } diff --git a/src/object/files.rs b/src/object/files.rs index eb32abc3da..f22ec55120 100644 --- a/src/object/files.rs +++ b/src/object/files.rs @@ -14,59 +14,33 @@ pub enum FileType { Symlink, } -impl DirEntry { - crate fn new(inner: std::fs::DirEntry) -> Result { - let mut dict = Dictionary::default(); - let filename = inner.file_name(); - dict.add("file name", Value::string(filename.to_string_lossy())); +crate fn dir_entry_dict(entry: &std::fs::DirEntry) -> Result { + let mut dict = Dictionary::default(); + let filename = entry.file_name(); + dict.add("file name", Value::string(filename.to_string_lossy())); - let metadata = inner.metadata()?; - // let file_type = inner.file_type()?; + let metadata = entry.metadata()?; + // let file_type = inner.file_type()?; - let kind = if metadata.is_dir() { - FileType::Directory - } else if metadata.is_file() { - FileType::File - } else { - FileType::Symlink - }; + let kind = if metadata.is_dir() { + FileType::Directory + } else if metadata.is_file() { + FileType::File + } else { + FileType::Symlink + }; - dict.add("file type", Value::string(format!("{:?}", kind))); - dict.add( - "readonly", - Value::boolean(metadata.permissions().readonly()), - ); + dict.add("file type", Value::string(format!("{:?}", kind))); + dict.add( + "readonly", + Value::boolean(metadata.permissions().readonly()), + ); - dict.add("size", Value::bytes(metadata.len() as u128)); + dict.add("size", Value::bytes(metadata.len() as u128)); - dict.add("created", Value::system_date_result(metadata.created())); - dict.add("accessed", Value::system_date_result(metadata.accessed())); - dict.add("modified", Value::system_date_result(metadata.modified())); + dict.add("created", Value::system_date_result(metadata.created())); + dict.add("accessed", Value::system_date_result(metadata.accessed())); + dict.add("modified", Value::system_date_result(metadata.modified())); - // dict.add("created_at", Value::date()) - - Ok(DirEntry { dict }) - } -} - -impl ShellObject for DirEntry { - fn to_shell_string(&self) -> String { - format!("[object DirEntry]") - } - - fn data_descriptors(&self) -> Vec { - self.dict.data_descriptors() - } - - fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> { - self.dict.get_data(desc) - } - - fn copy(&self) -> Value { - let copy = DirEntry { - dict: self.dict.copy_dict(), - }; - - Value::Object(Box::new(copy)) - } + Ok(dict) } diff --git a/src/object/process.rs b/src/object/process.rs index 7ba419d8e4..abea95fdcf 100644 --- a/src/object/process.rs +++ b/src/object/process.rs @@ -11,43 +11,21 @@ pub struct Process { dict: Dictionary, } -impl Process { - crate fn new(inner: sysinfo::Process) -> Process { - let mut dict = Dictionary::default(); - dict.add("name", Value::string(inner.name())); +crate fn process_dict(proc: &sysinfo::Process) -> Dictionary { + let mut dict = Dictionary::default(); + dict.add("name", Value::string(proc.name())); - let cmd = inner.cmd(); + let cmd = proc.cmd(); - let cmd_value = if cmd.len() == 0 { - Value::nothing() - } else { - Value::string(join(cmd, "")) - }; + let cmd_value = if cmd.len() == 0 { + Value::nothing() + } else { + Value::string(join(cmd, "")) + }; - dict.add("cmd", cmd_value); - dict.add("pid", Value::int(inner.pid() as i64)); - dict.add("status", Value::int(inner.status() as i64)); + dict.add("cmd", cmd_value); + dict.add("pid", Value::int(proc.pid() as i64)); + dict.add("status", Value::int(proc.status() as i64)); - Process { dict } - } -} - -impl ShellObject for Process { - fn to_shell_string(&self) -> String { - format!("Process") - } - - fn data_descriptors(&self) -> Vec { - self.dict.data_descriptors() - } - - fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> { - self.dict.get_data(desc) - } - - fn copy(&self) -> Value { - let copy = self.dict.copy_dict(); - - Value::Object(Box::new(copy)) - } + dict }