forked from extern/nushell
Split nu-cli into nu-cli/nu-engine (#2898)
We split off the evaluation engine part of nu-cli into its own crate. This helps improve build times for nu-cli by 17% in my tests. It also helps us see a bit better what's the core engine portion vs the part specific to the interactive CLI piece. There's more than can be done here, but I think it's a good start in the right direction.
This commit is contained in:
@ -24,4 +24,5 @@ pub use crate::value::did_you_mean::did_you_mean;
|
||||
pub use crate::value::primitive::Primitive;
|
||||
pub use crate::value::primitive::{format_date, format_duration, format_primitive};
|
||||
pub use crate::value::range::{Range, RangeInclusion};
|
||||
pub use crate::value::value_structure::{ValueResource, ValueStructure};
|
||||
pub use crate::value::{merge_descriptors, UntaggedValue, Value};
|
||||
|
@ -8,6 +8,7 @@ pub mod primitive;
|
||||
pub mod range;
|
||||
mod serde_bigdecimal;
|
||||
mod serde_bigint;
|
||||
pub mod value_structure;
|
||||
|
||||
use crate::hir;
|
||||
use crate::type_name::{ShellTypeName, SpannedTypeName};
|
||||
|
80
crates/nu-protocol/src/value/value_structure.rs
Normal file
80
crates/nu-protocol/src/value/value_structure.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use crate::{UntaggedValue, Value};
|
||||
use nu_errors::ShellError;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
|
||||
fn is_value_tagged_dir(value: &Value) -> bool {
|
||||
matches!(&value.value, UntaggedValue::Row(_) | UntaggedValue::Table(_))
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct ValueResource {
|
||||
pub at: usize,
|
||||
pub loc: PathBuf,
|
||||
}
|
||||
|
||||
impl ValueResource {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ValueStructure {
|
||||
pub resources: Vec<ValueResource>,
|
||||
}
|
||||
|
||||
impl ValueStructure {
|
||||
pub fn new() -> ValueStructure {
|
||||
ValueStructure {
|
||||
resources: Vec::<ValueResource>::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists(&self, path: &Path) -> bool {
|
||||
if path == Path::new("/") {
|
||||
return true;
|
||||
}
|
||||
|
||||
let path = if path.starts_with("/") {
|
||||
path.strip_prefix("/").unwrap_or(path)
|
||||
} else {
|
||||
path
|
||||
};
|
||||
|
||||
let comps: Vec<_> = path.components().map(Component::as_os_str).collect();
|
||||
|
||||
let mut is_there = true;
|
||||
|
||||
for (at, fragment) in comps.iter().enumerate() {
|
||||
is_there = is_there
|
||||
&& self
|
||||
.resources
|
||||
.iter()
|
||||
.any(|resource| at == resource.at && *fragment == resource.loc.as_os_str());
|
||||
}
|
||||
|
||||
is_there
|
||||
}
|
||||
|
||||
pub fn walk_decorate(&mut self, start: &Value) -> Result<(), ShellError> {
|
||||
self.resources = Vec::<ValueResource>::new();
|
||||
self.build(start, 0)?;
|
||||
self.resources.sort();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build(&mut self, src: &Value, lvl: usize) -> Result<(), ShellError> {
|
||||
for entry in src.row_entries() {
|
||||
let value = entry.1;
|
||||
let path = entry.0;
|
||||
|
||||
self.resources.push(ValueResource {
|
||||
at: lvl,
|
||||
loc: PathBuf::from(path),
|
||||
});
|
||||
|
||||
if is_value_tagged_dir(value) {
|
||||
self.build(value, lvl + 1)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user