mirror of
https://github.com/nushell/nushell.git
synced 2025-08-10 01:17:47 +02:00
Pipe external to internal
Each line is a string object
This commit is contained in:
13
src/cli.rs
13
src/cli.rs
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::commands::classified::{
|
||||
ClassifiedCommand, ClassifiedInputStream, ExternalCommand, InternalCommand,
|
||||
ClassifiedCommand, ClassifiedInputStream, ExternalCommand, InternalCommand, StreamNext,
|
||||
};
|
||||
use crate::context::Context;
|
||||
crate use crate::errors::ShellError;
|
||||
@ -185,7 +185,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
|
||||
(
|
||||
Some(ClassifiedCommand::External(left)),
|
||||
Some(ClassifiedCommand::External(_)),
|
||||
) => match left.run(ctx, input, true).await {
|
||||
) => match left.run(ctx, input, StreamNext::External).await {
|
||||
Ok(val) => val,
|
||||
Err(err) => return LineResult::Error(format!("{}", err.description())),
|
||||
},
|
||||
@ -196,12 +196,15 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
|
||||
) => unimplemented!(),
|
||||
|
||||
(
|
||||
Some(ClassifiedCommand::External(_)),
|
||||
Some(ClassifiedCommand::External(left)),
|
||||
Some(ClassifiedCommand::Internal(_)),
|
||||
) => unimplemented!(),
|
||||
) => match left.run(ctx, input, StreamNext::Internal).await {
|
||||
Ok(val) => val,
|
||||
Err(err) => return LineResult::Error(format!("{}", err.description())),
|
||||
},
|
||||
|
||||
(Some(ClassifiedCommand::External(left)), None) => {
|
||||
match left.run(ctx, input, false).await {
|
||||
match left.run(ctx, input, StreamNext::Last).await {
|
||||
Ok(val) => val,
|
||||
Err(err) => return LineResult::Error(format!("{}", err.description())),
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::prelude::*;
|
||||
use futures::compat::AsyncRead01CompatExt;
|
||||
use futures_codec::{Framed, LinesCodec};
|
||||
use std::sync::Arc;
|
||||
use subprocess::Exec;
|
||||
|
||||
@ -107,20 +109,29 @@ crate struct ExternalCommand {
|
||||
crate args: Vec<String>,
|
||||
}
|
||||
|
||||
crate enum StreamNext {
|
||||
Last,
|
||||
External,
|
||||
Internal,
|
||||
}
|
||||
|
||||
impl ExternalCommand {
|
||||
crate async fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
mut input: ClassifiedInputStream,
|
||||
stream_next: bool,
|
||||
stream_next: StreamNext,
|
||||
) -> Result<ClassifiedInputStream, ShellError> {
|
||||
let mut process = Exec::shell(&self.name)
|
||||
.args(&self.args)
|
||||
.cwd(context.env.lock().unwrap().cwd());
|
||||
|
||||
if stream_next {
|
||||
process = process.stdout(subprocess::Redirection::Pipe)
|
||||
}
|
||||
let mut process = match stream_next {
|
||||
StreamNext::Last => process,
|
||||
StreamNext::External | StreamNext::Internal => {
|
||||
process.stdout(subprocess::Redirection::Pipe)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(stdin) = input.stdin {
|
||||
process = process.stdin(stdin);
|
||||
@ -128,15 +139,31 @@ impl ExternalCommand {
|
||||
|
||||
let mut popen = process.popen().unwrap();
|
||||
|
||||
if stream_next {
|
||||
match &popen.stdout {
|
||||
None => unreachable!(),
|
||||
Some(stdout) => Ok(ClassifiedInputStream::from_stdout(stdout.try_clone()?)),
|
||||
match stream_next {
|
||||
StreamNext::Last => {
|
||||
popen.wait()?;
|
||||
Ok(ClassifiedInputStream::new())
|
||||
}
|
||||
StreamNext::External => {
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
Ok(ClassifiedInputStream::from_stdout(stdout))
|
||||
}
|
||||
StreamNext::Internal => {
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
let file = futures::io::AllowStdIo::new(stdout);
|
||||
let stream = Framed::new(file, LinesCodec {});
|
||||
let stream = stream.map(|line| Value::string(line.unwrap()));
|
||||
Ok(ClassifiedInputStream::from_input_stream(stream.boxed()))
|
||||
}
|
||||
} else {
|
||||
popen.stdin.take();
|
||||
popen.wait()?;
|
||||
Ok(ClassifiedInputStream::new())
|
||||
}
|
||||
|
||||
// if stream_next {
|
||||
// let stdout = popen.stdout.take().unwrap();
|
||||
// Ok(ClassifiedInputStream::from_stdout(stdout))
|
||||
// } else {
|
||||
// // popen.stdin.take();
|
||||
// popen.wait()?;
|
||||
// Ok(ClassifiedInputStream::new())
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
19
src/env/host.rs
vendored
19
src/env/host.rs
vendored
@ -1,9 +1,20 @@
|
||||
pub trait Host {
|
||||
fn out_terminal(&self) -> Box<term::StdoutTerminal>;
|
||||
fn err_terminal(&self) -> Box<term::StderrTerminal>;
|
||||
|
||||
fn stdout(&mut self, out: &str);
|
||||
fn stderr(&mut self, out: &str);
|
||||
}
|
||||
|
||||
impl Host for Box<dyn Host> {
|
||||
fn out_terminal(&self) -> Box<term::StdoutTerminal> {
|
||||
(**self).out_terminal()
|
||||
}
|
||||
|
||||
fn err_terminal(&self) -> Box<term::StderrTerminal> {
|
||||
(**self).err_terminal()
|
||||
}
|
||||
|
||||
fn stdout(&mut self, out: &str) {
|
||||
(**self).stdout(out)
|
||||
}
|
||||
@ -16,6 +27,14 @@ impl Host for Box<dyn Host> {
|
||||
crate struct BasicHost;
|
||||
|
||||
impl Host for BasicHost {
|
||||
fn out_terminal(&self) -> Box<term::StdoutTerminal> {
|
||||
term::stdout().unwrap()
|
||||
}
|
||||
|
||||
fn err_terminal(&self) -> Box<term::StderrTerminal> {
|
||||
term::stderr().unwrap()
|
||||
}
|
||||
|
||||
fn stdout(&mut self, out: &str) {
|
||||
match out {
|
||||
"\n" => println!(""),
|
||||
|
@ -10,16 +10,9 @@ crate use generic::GenericView;
|
||||
crate use table::TableView;
|
||||
|
||||
crate trait RenderView {
|
||||
fn render_view(&self, host: &dyn Host) -> Vec<String>;
|
||||
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError>;
|
||||
}
|
||||
|
||||
fn print_rendered(lines: &[String], host: &mut dyn Host) {
|
||||
for line in lines {
|
||||
host.stdout(line);
|
||||
}
|
||||
}
|
||||
|
||||
crate fn print_view(view: &impl RenderView, host: &mut Host) {
|
||||
// let mut ctx = context.lock().unwrap();
|
||||
crate::format::print_rendered(&view.render_view(host), host);
|
||||
crate fn print_view(view: &impl RenderView, host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
view.render_view(host)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use derive_new::new;
|
||||
// another_name : ...
|
||||
#[derive(new)]
|
||||
pub struct EntriesView {
|
||||
entries: Vec<(String, String)>,
|
||||
entries: Vec<(crate::object::DescriptorName, String)>,
|
||||
}
|
||||
|
||||
impl EntriesView {
|
||||
@ -31,17 +31,28 @@ impl EntriesView {
|
||||
}
|
||||
|
||||
impl RenderView for EntriesView {
|
||||
fn render_view(&self, _host: &dyn Host) -> Vec<String> {
|
||||
fn render_view(&self, _host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
if self.entries.len() == 0 {
|
||||
return vec![];
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let max_name_size: usize = self.entries.iter().map(|(n, _)| n.len()).max().unwrap();
|
||||
|
||||
self.entries
|
||||
let max_name_size: usize = self
|
||||
.entries
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{:width$} : {}", k, v, width = max_name_size))
|
||||
.collect()
|
||||
.map(|(n, _)| n.display().len())
|
||||
.max()
|
||||
.unwrap();
|
||||
|
||||
for (name, value) in &self.entries {
|
||||
println!(
|
||||
"{:width$} : {}",
|
||||
name.display(),
|
||||
value,
|
||||
width = max_name_size
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,26 +69,22 @@ impl EntriesListView {
|
||||
}
|
||||
|
||||
impl RenderView for EntriesListView {
|
||||
fn render_view(&self, host: &dyn Host) -> Vec<String> {
|
||||
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
if self.values.len() == 0 {
|
||||
return vec![];
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut strings = vec![];
|
||||
|
||||
let last = self.values.len() - 1;
|
||||
|
||||
for (i, item) in self.values.iter().enumerate() {
|
||||
let view = EntriesView::from_value(item);
|
||||
let out = view.render_view(host);
|
||||
|
||||
strings.extend(out);
|
||||
view.render_view(host);
|
||||
|
||||
if i != last {
|
||||
strings.push("\n".to_string());
|
||||
host.stdout("\n");
|
||||
}
|
||||
}
|
||||
|
||||
strings
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -10,17 +10,17 @@ pub struct GenericView<'value> {
|
||||
}
|
||||
|
||||
impl RenderView for GenericView<'value> {
|
||||
fn render_view(&self, host: &dyn Host) -> Vec<String> {
|
||||
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
match self.value {
|
||||
Value::Primitive(p) => vec![p.format(None)],
|
||||
Value::Primitive(p) => Ok(host.stdout(&p.format(None))),
|
||||
Value::List(l) => {
|
||||
let view = TableView::from_list(l);
|
||||
|
||||
if let Some(view) = view {
|
||||
view.render_view(host)
|
||||
} else {
|
||||
vec![]
|
||||
view.render_view(host);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
// let mut list: Vec<String> = vec![];
|
||||
// for item in l {
|
||||
// match item {
|
||||
@ -39,11 +39,14 @@ impl RenderView for GenericView<'value> {
|
||||
|
||||
o @ Value::Object(_) => {
|
||||
let view = EntriesView::from_value(o);
|
||||
let out = view.render_view(host);
|
||||
out
|
||||
view.render_view(host);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Value::Error(e) => vec![format!("{}", e)],
|
||||
Value::Error(e) => {
|
||||
host.stdout(&format!("{:?}", e));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,12 @@ pub struct ListView {
|
||||
}
|
||||
|
||||
impl RenderView for ListView {
|
||||
fn render_view(&self, _host: &dyn Host) -> Vec<String> {
|
||||
let mut out = vec![];
|
||||
|
||||
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
for output in &self.list {
|
||||
let string: String = output.iter().map(|l| format!("{}\n", l)).collect();
|
||||
out.push(format!("{}{}", string, self.sep));
|
||||
host.stdout(&format!("{}{}", string, self.sep));
|
||||
}
|
||||
|
||||
out
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::format::RenderView;
|
||||
use crate::object::Value;
|
||||
use crate::prelude::*;
|
||||
use ansi_term::Color;
|
||||
use derive_new::new;
|
||||
use prettytable::{Cell, Row, Table};
|
||||
use prettytable::{color, Attr, Cell, Row, Table};
|
||||
|
||||
// An entries list is printed like this:
|
||||
//
|
||||
@ -24,7 +25,7 @@ impl TableView {
|
||||
let item = &values[0];
|
||||
let descs = item.data_descriptors();
|
||||
|
||||
let headers: Vec<String> = descs.iter().map(|d| d.name.clone()).collect();
|
||||
let headers: Vec<String> = descs.iter().map(|d| d.name.display().to_string()).collect();
|
||||
|
||||
let mut entries = vec![];
|
||||
|
||||
@ -43,13 +44,27 @@ impl TableView {
|
||||
}
|
||||
|
||||
impl RenderView for TableView {
|
||||
fn render_view(&self, _host: &dyn Host) -> Vec<String> {
|
||||
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError> {
|
||||
if self.entries.len() == 0 {
|
||||
return vec![];
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut table = Table::new();
|
||||
let header: Vec<Cell> = self.headers.iter().map(|h| Cell::new(h)).collect();
|
||||
|
||||
// let format = prettytable::format::FormatBuilder::new();
|
||||
// .column_separator(Color::Black.bold().paint("|"));
|
||||
|
||||
table.set_format(*prettytable::format::consts::FORMAT_NO_COLSEP);
|
||||
|
||||
let header: Vec<Cell> = self
|
||||
.headers
|
||||
.iter()
|
||||
.map(|h| {
|
||||
Cell::new(h)
|
||||
.with_style(Attr::ForegroundColor(color::GREEN))
|
||||
.with_style(Attr::Bold)
|
||||
})
|
||||
.collect();
|
||||
|
||||
table.add_row(Row::new(header));
|
||||
|
||||
@ -57,9 +72,8 @@ impl RenderView for TableView {
|
||||
table.add_row(Row::new(row.iter().map(|h| Cell::new(h)).collect()));
|
||||
}
|
||||
|
||||
let mut out = vec![];
|
||||
table.print(&mut out).unwrap();
|
||||
table.print_term(&mut *host.out_terminal()).unwrap();
|
||||
|
||||
vec![String::from_utf8_lossy(&out).to_string()]
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,6 @@ crate mod process;
|
||||
crate mod types;
|
||||
|
||||
crate use base::{Primitive, Value};
|
||||
crate use desc::{DataDescriptor, DescriptorName};
|
||||
crate use dict::Dictionary;
|
||||
crate use files::dir_entry_dict;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::desc::DataDescriptor;
|
||||
use crate::object::{DataDescriptor, DescriptorName};
|
||||
use crate::parser::parse::Operator;
|
||||
use crate::prelude::*;
|
||||
use ansi_term::Color;
|
||||
@ -69,7 +69,7 @@ pub enum Value {
|
||||
impl Value {
|
||||
crate fn data_descriptors(&self) -> Vec<DataDescriptor> {
|
||||
match self {
|
||||
Value::Primitive(_) => vec![],
|
||||
Value::Primitive(_) => vec![DataDescriptor::value_of()],
|
||||
Value::Object(o) => o.data_descriptors(),
|
||||
Value::List(_) => vec![],
|
||||
Value::Error(_) => vec![],
|
||||
@ -87,7 +87,7 @@ impl Value {
|
||||
|
||||
crate fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> {
|
||||
match self {
|
||||
Value::Primitive(_) => MaybeOwned::Owned(Value::nothing()),
|
||||
p @ Value::Primitive(_) => MaybeOwned::Borrowed(p),
|
||||
Value::Object(o) => o.get_data(desc),
|
||||
Value::List(_) => MaybeOwned::Owned(Value::nothing()),
|
||||
Value::Error(_) => MaybeOwned::Owned(Value::nothing()),
|
||||
@ -203,9 +203,9 @@ crate fn select_fields(obj: &Value, fields: &[String]) -> crate::object::Diction
|
||||
let descs = obj.data_descriptors();
|
||||
|
||||
for field in fields {
|
||||
match descs.iter().find(|d| d.name == *field) {
|
||||
None => out.add(field.to_string(), Value::nothing()),
|
||||
Some(desc) => out.add(field.to_string(), obj.get_data(desc).borrow().copy()),
|
||||
match descs.iter().find(|d| d.name.is_string(field)) {
|
||||
None => out.add(DataDescriptor::for_string_name(field), Value::nothing()),
|
||||
Some(desc) => out.add(desc.copy(), obj.get_data(desc).borrow().copy()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,10 +218,10 @@ crate fn reject_fields(obj: &Value, fields: &[String]) -> crate::object::Diction
|
||||
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())
|
||||
match desc.name.as_string() {
|
||||
None => continue,
|
||||
Some(s) if fields.iter().any(|field| field == s) => continue,
|
||||
Some(s) => out.add(desc.copy(), obj.get_data(&desc).borrow().copy()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ crate fn reject_fields(obj: &Value, fields: &[String]) -> crate::object::Diction
|
||||
|
||||
crate fn find(obj: &Value, field: &str, op: &Operator, rhs: &Value) -> bool {
|
||||
let descs = obj.data_descriptors();
|
||||
match descs.iter().find(|d| d.name == *field) {
|
||||
match descs.iter().find(|d| d.name.is_string(field)) {
|
||||
None => false,
|
||||
Some(desc) => {
|
||||
let v = obj.get_data(desc).borrow().copy();
|
||||
|
@ -1,17 +1,110 @@
|
||||
use crate::object::types::Type;
|
||||
use crate::object::types::{AnyShell, Type};
|
||||
use derive_new::new;
|
||||
|
||||
#[derive(new)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum DescriptorName {
|
||||
String(String),
|
||||
ValueOf,
|
||||
}
|
||||
|
||||
impl DescriptorName {
|
||||
crate fn display(&self) -> &str {
|
||||
match self {
|
||||
DescriptorName::String(s) => s,
|
||||
DescriptorName::ValueOf => "value",
|
||||
}
|
||||
}
|
||||
|
||||
crate fn as_string(&self) -> Option<&str> {
|
||||
match self {
|
||||
DescriptorName::String(s) => Some(s),
|
||||
DescriptorName::ValueOf => None,
|
||||
}
|
||||
}
|
||||
|
||||
crate fn is_string(&self, string: &str) -> bool {
|
||||
match self {
|
||||
DescriptorName::String(s) => s == string,
|
||||
DescriptorName::ValueOf => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, new)]
|
||||
pub struct DataDescriptor {
|
||||
crate name: String,
|
||||
crate name: DescriptorName,
|
||||
crate readonly: bool,
|
||||
crate ty: Box<dyn Type>,
|
||||
}
|
||||
|
||||
impl From<&str> for DataDescriptor {
|
||||
fn from(input: &str) -> DataDescriptor {
|
||||
DataDescriptor {
|
||||
name: DescriptorName::String(input.to_string()),
|
||||
readonly: true,
|
||||
ty: Box::new(AnyShell),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for DataDescriptor {
|
||||
fn from(input: String) -> DataDescriptor {
|
||||
DataDescriptor {
|
||||
name: DescriptorName::String(input),
|
||||
readonly: true,
|
||||
ty: Box::new(AnyShell),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for DataDescriptor {
|
||||
fn eq(&self, other: &DataDescriptor) -> bool {
|
||||
self.name == other.name && self.readonly == other.readonly && self.ty.equal(&*other.ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl DataDescriptor {}
|
||||
impl std::hash::Hash for DataDescriptor {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
self.readonly.hash(state);
|
||||
self.ty.id().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for DataDescriptor {}
|
||||
|
||||
impl DescriptorName {
|
||||
crate fn for_string_name(name: impl Into<String>) -> DescriptorName {
|
||||
DescriptorName::String(name.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl DataDescriptor {
|
||||
crate fn value_of() -> DataDescriptor {
|
||||
DataDescriptor {
|
||||
name: DescriptorName::ValueOf,
|
||||
readonly: true,
|
||||
ty: Box::new(AnyShell),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn for_name(name: impl Into<DescriptorName>) -> DataDescriptor {
|
||||
DataDescriptor {
|
||||
name: name.into(),
|
||||
readonly: true,
|
||||
ty: Box::new(AnyShell),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn for_string_name(name: impl Into<String>) -> DataDescriptor {
|
||||
DataDescriptor::for_name(DescriptorName::for_string_name(name))
|
||||
}
|
||||
|
||||
crate fn copy(&self) -> DataDescriptor {
|
||||
DataDescriptor {
|
||||
name: self.name.clone(),
|
||||
readonly: self.readonly,
|
||||
ty: self.ty.copy(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::object::desc::DataDescriptor;
|
||||
use crate::object::{DataDescriptor, DescriptorName};
|
||||
use crate::object::{Primitive, Value};
|
||||
use indexmap::IndexMap;
|
||||
use std::cmp::{Ordering, PartialOrd};
|
||||
|
||||
#[derive(Debug, Default, Eq, PartialEq)]
|
||||
pub struct Dictionary {
|
||||
entries: IndexMap<String, Value>,
|
||||
entries: IndexMap<DataDescriptor, Value>,
|
||||
}
|
||||
|
||||
impl PartialOrd for Dictionary {
|
||||
@ -41,7 +41,7 @@ impl PartialEq<Value> for Dictionary {
|
||||
}
|
||||
|
||||
impl Dictionary {
|
||||
crate fn add(&mut self, name: impl Into<String>, value: Value) {
|
||||
crate fn add(&mut self, name: impl Into<DataDescriptor>, value: Value) {
|
||||
self.entries.insert(name.into(), value);
|
||||
}
|
||||
|
||||
@ -49,31 +49,30 @@ impl Dictionary {
|
||||
let mut out = Dictionary::default();
|
||||
|
||||
for (key, value) in self.entries.iter() {
|
||||
out.add(key.clone(), value.copy());
|
||||
out.add(key.copy(), value.copy());
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
crate fn data_descriptors(&self) -> Vec<DataDescriptor> {
|
||||
self.entries
|
||||
.iter()
|
||||
.map(|(name, _)| {
|
||||
DataDescriptor::new(name.clone(), true, Box::new(crate::object::types::AnyShell))
|
||||
})
|
||||
.collect()
|
||||
self.entries.iter().map(|(name, _)| name.copy()).collect()
|
||||
}
|
||||
|
||||
crate fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> {
|
||||
match self.entries.get(&desc.name) {
|
||||
match self.entries.get(desc) {
|
||||
Some(v) => MaybeOwned::Borrowed(v),
|
||||
None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)),
|
||||
}
|
||||
}
|
||||
|
||||
crate fn get_data_by_key(&self, name: &str) -> MaybeOwned<'_, Value> {
|
||||
match self.entries.get(name) {
|
||||
Some(v) => MaybeOwned::Borrowed(v),
|
||||
match self
|
||||
.entries
|
||||
.iter()
|
||||
.find(|(desc_name, _)| desc_name.name.is_string(name))
|
||||
{
|
||||
Some((_, v)) => MaybeOwned::Borrowed(v),
|
||||
None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)),
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait Type {
|
||||
pub trait Type: Debug + Send {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn equal(&self, other: &dyn Type) -> bool;
|
||||
fn id(&self) -> u64;
|
||||
fn copy(&self) -> Box<Type>;
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct AnyShell;
|
||||
|
||||
impl Type for AnyShell {
|
||||
@ -16,4 +19,12 @@ impl Type for AnyShell {
|
||||
fn equal(&self, other: &dyn Type) -> bool {
|
||||
other.as_any().is::<AnyShell>()
|
||||
}
|
||||
|
||||
fn id(&self) -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
fn copy(&self) -> Box<Type> {
|
||||
Box::new(AnyShell)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user