forked from extern/nushell
Reduce again the number of match calls (#7815)
- Reduce the number of match calls (see commit messages) - A few miscellaneous improvements
This commit is contained in:
parent
0bb2e47c98
commit
41306aa7e0
@ -56,12 +56,11 @@ pub fn add_plugin_file(
|
|||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
let cwd = working_set.get_cwd();
|
let cwd = working_set.get_cwd();
|
||||||
|
|
||||||
match canonicalize_with(&plugin_file.item, cwd) {
|
if let Ok(path) = canonicalize_with(&plugin_file.item, cwd) {
|
||||||
Ok(path) => engine_state.plugin_signatures = Some(path),
|
engine_state.plugin_signatures = Some(path)
|
||||||
Err(_) => {
|
} else {
|
||||||
let e = ParseError::FileNotFound(plugin_file.item, plugin_file.span);
|
let e = ParseError::FileNotFound(plugin_file.item, plugin_file.span);
|
||||||
report_error(&working_set, &e);
|
report_error(&working_set, &e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if let Some(mut plugin_path) = nu_path::config_dir() {
|
} else if let Some(mut plugin_path) = nu_path::config_dir() {
|
||||||
// Path to store plugins signatures
|
// Path to store plugins signatures
|
||||||
|
@ -81,13 +81,10 @@ fn convert_to_suggestions(
|
|||||||
) -> Vec<Suggestion> {
|
) -> Vec<Suggestion> {
|
||||||
match value {
|
match value {
|
||||||
Value::Record { .. } => {
|
Value::Record { .. } => {
|
||||||
let text = match value
|
let text = value
|
||||||
.get_data_by_key("value")
|
.get_data_by_key("value")
|
||||||
.and_then(|val| val.as_string().ok())
|
.and_then(|val| val.as_string().ok())
|
||||||
{
|
.unwrap_or_else(|| "No value key".to_string());
|
||||||
Some(val) => val,
|
|
||||||
None => "No value key".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let description = value
|
let description = value
|
||||||
.get_data_by_key("description")
|
.get_data_by_key("description")
|
||||||
|
@ -77,20 +77,17 @@ fn get_prompt_string(
|
|||||||
.and_then(|pipeline_data| {
|
.and_then(|pipeline_data| {
|
||||||
let output = pipeline_data.collect_string("", config).ok();
|
let output = pipeline_data.collect_string("", config).ok();
|
||||||
|
|
||||||
match output {
|
output.map(|mut x| {
|
||||||
Some(mut x) => {
|
// Just remove the very last newline.
|
||||||
// Just remove the very last newline.
|
if x.ends_with('\n') {
|
||||||
if x.ends_with('\n') {
|
x.pop();
|
||||||
x.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if x.ends_with('\r') {
|
|
||||||
x.pop();
|
|
||||||
}
|
|
||||||
Some(x)
|
|
||||||
}
|
}
|
||||||
None => None,
|
|
||||||
}
|
if x.ends_with('\r') {
|
||||||
|
x.pop();
|
||||||
|
}
|
||||||
|
x
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,12 +104,13 @@ pub(crate) fn update_prompt<'prompt>(
|
|||||||
// Now that we have the prompt string lets ansify it.
|
// Now that we have the prompt string lets ansify it.
|
||||||
// <133 A><prompt><133 B><command><133 C><command output>
|
// <133 A><prompt><133 B><command><133 C><command output>
|
||||||
let left_prompt_string = if config.shell_integration {
|
let left_prompt_string = if config.shell_integration {
|
||||||
match left_prompt_string {
|
if let Some(prompt_string) = left_prompt_string {
|
||||||
Some(prompt_string) => Some(format!(
|
Some(format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
PRE_PROMPT_MARKER, prompt_string, POST_PROMPT_MARKER
|
PRE_PROMPT_MARKER, prompt_string, POST_PROMPT_MARKER
|
||||||
)),
|
))
|
||||||
None => left_prompt_string,
|
} else {
|
||||||
|
left_prompt_string
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
left_prompt_string
|
left_prompt_string
|
||||||
|
@ -651,14 +651,15 @@ fn add_parsed_keybinding(
|
|||||||
let pos1 = char_iter.next();
|
let pos1 = char_iter.next();
|
||||||
let pos2 = char_iter.next();
|
let pos2 = char_iter.next();
|
||||||
|
|
||||||
let char = match (pos1, pos2) {
|
let char = if let (Some(char), None) = (pos1, pos2) {
|
||||||
(Some(char), None) => Ok(char),
|
char
|
||||||
_ => Err(ShellError::UnsupportedConfigValue(
|
} else {
|
||||||
|
return Err(ShellError::UnsupportedConfigValue(
|
||||||
"char_<CHAR: unicode codepoint>".to_string(),
|
"char_<CHAR: unicode codepoint>".to_string(),
|
||||||
c.to_string(),
|
c.to_string(),
|
||||||
keybinding.keycode.span()?,
|
keybinding.keycode.span()?,
|
||||||
)),
|
));
|
||||||
}?;
|
};
|
||||||
|
|
||||||
KeyCode::Char(char)
|
KeyCode::Char(char)
|
||||||
}
|
}
|
||||||
|
@ -1002,18 +1002,15 @@ fn run_hook_block(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> {
|
fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> {
|
||||||
match io::stdout().write_all(seq.as_bytes()) {
|
io::stdout().write_all(seq.as_bytes()).map_err(|e| {
|
||||||
Ok(it) => it,
|
ShellError::GenericError(
|
||||||
Err(err) => {
|
"Error writing ansi sequence".into(),
|
||||||
return Err(ShellError::GenericError(
|
e.to_string(),
|
||||||
"Error writing ansi sequence".into(),
|
Some(Span::unknown()),
|
||||||
err.to_string(),
|
None,
|
||||||
Some(Span::unknown()),
|
Vec::new(),
|
||||||
None,
|
)
|
||||||
Vec::new(),
|
})?;
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
io::stdout().flush().map_err(|e| {
|
io::stdout().flush().map_err(|e| {
|
||||||
ShellError::GenericError(
|
ShellError::GenericError(
|
||||||
"Error flushing stdio".into(),
|
"Error flushing stdio".into(),
|
||||||
|
@ -315,27 +315,19 @@ pub fn report_error_new(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_init_cwd() -> PathBuf {
|
pub fn get_init_cwd() -> PathBuf {
|
||||||
match std::env::current_dir() {
|
std::env::current_dir().unwrap_or_else(|_| {
|
||||||
Ok(cwd) => cwd,
|
std::env::var("PWD")
|
||||||
Err(_) => match std::env::var("PWD") {
|
.map(Into::into)
|
||||||
Ok(cwd) => PathBuf::from(cwd),
|
.unwrap_or_else(|_| nu_path::home_dir().unwrap_or_default())
|
||||||
Err(_) => match nu_path::home_dir() {
|
})
|
||||||
Some(cwd) => cwd,
|
|
||||||
None => PathBuf::new(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf {
|
pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf {
|
||||||
match nu_engine::env::current_dir(engine_state, stack) {
|
nu_engine::env::current_dir(engine_state, stack).unwrap_or_else(|e| {
|
||||||
Ok(p) => p,
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
Err(e) => {
|
report_error(&working_set, &e);
|
||||||
let working_set = StateWorkingSet::new(engine_state);
|
get_init_cwd()
|
||||||
report_error(&working_set, &e);
|
})
|
||||||
get_init_cwd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -98,32 +98,26 @@ fn parse_range(range: Value, head: Span) -> Result<(isize, isize, Span), ShellEr
|
|||||||
let start: isize = if start.is_empty() || start == "_" {
|
let start: isize = if start.is_empty() || start == "_" {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
match start.trim().parse() {
|
start.trim().parse().map_err(|_| {
|
||||||
Ok(s) => s,
|
ShellError::UnsupportedInput(
|
||||||
Err(_) => {
|
"could not perform subbytes".to_string(),
|
||||||
return Err(ShellError::UnsupportedInput(
|
"with this range".to_string(),
|
||||||
"could not perform subbytes".to_string(),
|
head,
|
||||||
"with this range".to_string(),
|
span,
|
||||||
head,
|
)
|
||||||
span,
|
})?
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let end: isize = if end.is_empty() || end == "_" {
|
let end: isize = if end.is_empty() || end == "_" {
|
||||||
isize::max_value()
|
isize::max_value()
|
||||||
} else {
|
} else {
|
||||||
match end.trim().parse() {
|
end.trim().parse().map_err(|_| {
|
||||||
Ok(s) => s,
|
ShellError::UnsupportedInput(
|
||||||
Err(_) => {
|
"could not perform subbytes".to_string(),
|
||||||
return Err(ShellError::UnsupportedInput(
|
"with this range".to_string(),
|
||||||
"could not perform subbytes".to_string(),
|
head,
|
||||||
"with this range".to_string(),
|
span,
|
||||||
head,
|
)
|
||||||
span,
|
})?
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok((start, end, span))
|
Ok((start, end, span))
|
||||||
}
|
}
|
||||||
|
@ -129,18 +129,15 @@ impl Command for Histogram {
|
|||||||
let span = call.head;
|
let span = call.head;
|
||||||
let data_as_value = input.into_value(span);
|
let data_as_value = input.into_value(span);
|
||||||
// `input` is not a list, here we can return an error.
|
// `input` is not a list, here we can return an error.
|
||||||
match data_as_value.as_list() {
|
run_histogram(
|
||||||
Ok(list_value) => run_histogram(
|
data_as_value.as_list()?.to_vec(),
|
||||||
list_value.to_vec(),
|
column_name,
|
||||||
column_name,
|
frequency_column_name,
|
||||||
frequency_column_name,
|
calc_method,
|
||||||
calc_method,
|
span,
|
||||||
span,
|
// Note that as_list() filters out Value::Error here.
|
||||||
// Note that as_list() filters out Value::Error here.
|
data_as_value.expect_span(),
|
||||||
data_as_value.expect_span(),
|
)
|
||||||
),
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,12 +234,7 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
|||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
Value::Error { error } => Value::String {
|
Value::Error { error } => Value::String {
|
||||||
val: {
|
val: into_code(error).unwrap_or_default(),
|
||||||
match into_code(error) {
|
|
||||||
Some(code) => code,
|
|
||||||
None => "".to_string(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
Value::Nothing { .. } => Value::String {
|
Value::Nothing { .. } => Value::String {
|
||||||
|
@ -107,12 +107,7 @@ impl SQLiteDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_connection(&self) -> Result<Connection, rusqlite::Error> {
|
pub fn open_connection(&self) -> Result<Connection, rusqlite::Error> {
|
||||||
let conn = match Connection::open(&self.path) {
|
Connection::open(&self.path)
|
||||||
Ok(conn) => conn,
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(conn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tables(&self, conn: &Connection) -> Result<Vec<DbTable>, rusqlite::Error> {
|
pub fn get_tables(&self, conn: &Connection) -> Result<Vec<DbTable>, rusqlite::Error> {
|
||||||
@ -582,18 +577,13 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_connection_in_memory() -> Result<Connection, ShellError> {
|
pub fn open_connection_in_memory() -> Result<Connection, ShellError> {
|
||||||
let db = match Connection::open_in_memory() {
|
Connection::open_in_memory().map_err(|err| {
|
||||||
Ok(conn) => conn,
|
ShellError::GenericError(
|
||||||
Err(err) => {
|
"Failed to open SQLite connection in memory".into(),
|
||||||
return Err(ShellError::GenericError(
|
err.to_string(),
|
||||||
"Failed to open SQLite connection in memory".into(),
|
Some(Span::test_data()),
|
||||||
err.to_string(),
|
None,
|
||||||
Some(Span::test_data()),
|
Vec::new(),
|
||||||
None,
|
)
|
||||||
Vec::new(),
|
})
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(db)
|
|
||||||
}
|
}
|
||||||
|
@ -51,9 +51,8 @@ impl Command for ListDF {
|
|||||||
|
|
||||||
let vals = vals
|
let vals = vals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(name, value)| match NuDataFrame::try_from_value(value) {
|
.filter_map(|(name, value)| {
|
||||||
Ok(df) => Some((name, df)),
|
NuDataFrame::try_from_value(value).ok().map(|df| (name, df))
|
||||||
Err(_) => None,
|
|
||||||
})
|
})
|
||||||
.map(|(name, df)| {
|
.map(|(name, df)| {
|
||||||
let name = Value::String {
|
let name = Value::String {
|
||||||
|
@ -103,14 +103,13 @@ fn command(
|
|||||||
|
|
||||||
let type_id = match &type_option {
|
let type_id = match &type_option {
|
||||||
Some(ref t) => Some((t.item.to_owned(), "Invalid type", t.span)),
|
Some(ref t) => Some((t.item.to_owned(), "Invalid type", t.span)),
|
||||||
None => match file.item.extension() {
|
None => file.item.extension().map(|e| {
|
||||||
Some(e) => Some((
|
(
|
||||||
e.to_string_lossy().into_owned(),
|
e.to_string_lossy().into_owned(),
|
||||||
"Invalid extension",
|
"Invalid extension",
|
||||||
file.span,
|
file.span,
|
||||||
)),
|
)
|
||||||
None => None,
|
}),
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match type_id {
|
match type_id {
|
||||||
|
@ -71,32 +71,30 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
|
|||||||
|
|
||||||
let mut stack = Stack::new();
|
let mut stack = Stack::new();
|
||||||
|
|
||||||
match eval_block(
|
let result = eval_block(
|
||||||
&engine_state,
|
&engine_state,
|
||||||
&mut stack,
|
&mut stack,
|
||||||
&block,
|
&block,
|
||||||
PipelineData::empty(),
|
PipelineData::empty(),
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
) {
|
)
|
||||||
Err(err) => panic!("test eval error in `{}`: {:?}", example.example, err),
|
.unwrap_or_else(|err| panic!("test eval error in `{}`: {:?}", example.example, err))
|
||||||
Ok(result) => {
|
.into_value(Span::test_data());
|
||||||
let result = result.into_value(Span::test_data());
|
|
||||||
println!("input: {}", example.example);
|
|
||||||
println!("result: {:?}", result);
|
|
||||||
println!("done: {:?}", start.elapsed());
|
|
||||||
|
|
||||||
// Note. Value implements PartialEq for Bool, Int, Float, String and Block
|
println!("input: {}", example.example);
|
||||||
// If the command you are testing requires to compare another case, then
|
println!("result: {:?}", result);
|
||||||
// you need to define its equality in the Value struct
|
println!("done: {:?}", start.elapsed());
|
||||||
if let Some(expected) = example.result {
|
|
||||||
if result != expected {
|
// Note. Value implements PartialEq for Bool, Int, Float, String and Block
|
||||||
panic!(
|
// If the command you are testing requires to compare another case, then
|
||||||
"the example result is different to expected value: {:?} != {:?}",
|
// you need to define its equality in the Value struct
|
||||||
result, expected
|
if let Some(expected) = example.result {
|
||||||
)
|
if result != expected {
|
||||||
}
|
panic!(
|
||||||
}
|
"the example result is different to expected value: {:?} != {:?}",
|
||||||
|
result, expected
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,22 +306,19 @@ mod test_examples {
|
|||||||
engine_state: &mut Box<EngineState>,
|
engine_state: &mut Box<EngineState>,
|
||||||
) -> Option<Value> {
|
) -> Option<Value> {
|
||||||
let (mut block, delta) = parse(src, engine_state);
|
let (mut block, delta) = parse(src, engine_state);
|
||||||
match block.pipelines.len() {
|
if block.pipelines.len() == 1 {
|
||||||
1 => {
|
let n_expressions = block.pipelines[0].elements.len();
|
||||||
let n_expressions = block.pipelines[0].elements.len();
|
block.pipelines[0].elements.truncate(&n_expressions - 1);
|
||||||
block.pipelines[0].elements.truncate(&n_expressions - 1);
|
|
||||||
|
|
||||||
if !block.pipelines[0].elements.is_empty() {
|
if !block.pipelines[0].elements.is_empty() {
|
||||||
let empty_input = PipelineData::empty();
|
let empty_input = PipelineData::empty();
|
||||||
Some(eval_block(block, empty_input, cwd, engine_state, delta))
|
Some(eval_block(block, empty_input, cwd, engine_state, delta))
|
||||||
} else {
|
} else {
|
||||||
Some(Value::nothing(Span::test_data()))
|
Some(Value::nothing(Span::test_data()))
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// E.g. multiple semicolon-separated statements
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// E.g. multiple semicolon-separated statements
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,7 @@ impl NuProgressBar {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let total_bytes = match total_bytes {
|
let total_bytes = total_bytes.unwrap_or_default();
|
||||||
Some(total_size) => total_size,
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_progress_bar = ProgressBar::new(total_bytes);
|
let new_progress_bar = ProgressBar::new(total_bytes);
|
||||||
new_progress_bar.set_style(
|
new_progress_bar.set_style(
|
||||||
|
@ -45,16 +45,13 @@ pub fn sort_value_in_place(
|
|||||||
insensitive: bool,
|
insensitive: bool,
|
||||||
natural: bool,
|
natural: bool,
|
||||||
) -> Result<(), ShellError> {
|
) -> Result<(), ShellError> {
|
||||||
match val {
|
if let Value::List { vals, span } = val {
|
||||||
Value::List { vals, span } => {
|
sort(vals, sort_columns, *span, insensitive, natural)?;
|
||||||
sort(vals, sort_columns, *span, insensitive, natural)?;
|
if !ascending {
|
||||||
if !ascending {
|
vals.reverse();
|
||||||
vals.reverse();
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
_ => Ok(()),
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sort(
|
pub fn sort(
|
||||||
@ -102,10 +99,9 @@ pub fn sort(
|
|||||||
let mut vals = vec![];
|
let mut vals = vec![];
|
||||||
for item in vec.iter() {
|
for item in vec.iter() {
|
||||||
for col in &sort_columns {
|
for col in &sort_columns {
|
||||||
let val = match item.get_data_by_key(col) {
|
let val = item
|
||||||
Some(v) => v,
|
.get_data_by_key(col)
|
||||||
None => Value::nothing(Span::unknown()),
|
.unwrap_or_else(|| Value::nothing(Span::unknown()));
|
||||||
};
|
|
||||||
vals.push(val);
|
vals.push(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,15 +53,12 @@ impl SimpleCommand for TweakCmd {
|
|||||||
let input = input.trim();
|
let input = input.trim();
|
||||||
|
|
||||||
let args = input.split_once(' ');
|
let args = input.split_once(' ');
|
||||||
let (key, value) = match args {
|
let (key, value) = args.ok_or_else(|| {
|
||||||
Some(args) => args,
|
io::Error::new(
|
||||||
None => {
|
io::ErrorKind::Other,
|
||||||
return Err(io::Error::new(
|
"expected to get 2 arguments 'key value'",
|
||||||
io::ErrorKind::Other,
|
)
|
||||||
"expected to get 2 arguments 'key value'",
|
})?;
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.value = parse_value(value);
|
self.value = parse_value(value);
|
||||||
|
|
||||||
|
@ -171,15 +171,8 @@ fn create_help_manual(cmd: &Command) -> HelpManual {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn __create_help_manual(manual: Option<HelpManual>, name: &'static str) -> HelpManual {
|
fn __create_help_manual(manual: Option<HelpManual>, name: &'static str) -> HelpManual {
|
||||||
match manual {
|
manual.unwrap_or(HelpManual {
|
||||||
Some(manual) => manual,
|
name,
|
||||||
None => HelpManual {
|
..HelpManual::default()
|
||||||
name,
|
})
|
||||||
description: "",
|
|
||||||
arguments: Vec::new(),
|
|
||||||
examples: Vec::new(),
|
|
||||||
input: Vec::new(),
|
|
||||||
config_options: Vec::new(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,11 @@ pub fn run_command_with_value(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pipeline = PipelineData::Value(input.clone(), None);
|
let pipeline = PipelineData::Value(input.clone(), None);
|
||||||
let pipeline = run_nu_command(engine_state, stack, command, pipeline);
|
let pipeline = run_nu_command(engine_state, stack, command, pipeline)?;
|
||||||
match pipeline {
|
if let PipelineData::Value(Value::Error { error }, ..) = pipeline {
|
||||||
Ok(PipelineData::Value(Value::Error { error }, ..)) => {
|
Err(ShellError::IOError(error.to_string()))
|
||||||
Err(ShellError::IOError(error.to_string()))
|
} else {
|
||||||
}
|
Ok(pipeline)
|
||||||
Ok(pipeline) => Ok(pipeline),
|
|
||||||
Err(err) => Err(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,14 +87,9 @@ fn try_build_list(
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
let val = table.draw(table_config, usize::MAX);
|
table.draw(table_config, usize::MAX).unwrap_or_else(|| {
|
||||||
|
value_to_styled_string(&Value::List { vals, span }, config, style_computer).0
|
||||||
match val {
|
})
|
||||||
Some(result) => result,
|
|
||||||
None => {
|
|
||||||
value_to_styled_string(&Value::List { vals, span }, config, style_computer).0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(None) | Err(_) => {
|
Ok(None) | Err(_) => {
|
||||||
// it means that the list is empty
|
// it means that the list is empty
|
||||||
@ -848,10 +843,8 @@ fn make_styled_string(
|
|||||||
match value {
|
match value {
|
||||||
Value::Float { .. } => {
|
Value::Float { .. } => {
|
||||||
// set dynamic precision from config
|
// set dynamic precision from config
|
||||||
let precise_number = match convert_with_precision(&text, float_precision) {
|
let precise_number = convert_with_precision(&text, float_precision)
|
||||||
Ok(num) => num,
|
.unwrap_or_else(|e| e.to_string());
|
||||||
Err(e) => e.to_string(),
|
|
||||||
};
|
|
||||||
(precise_number, style_computer.style_primitive(value))
|
(precise_number, style_computer.style_primitive(value))
|
||||||
}
|
}
|
||||||
_ => (text, style_computer.style_primitive(value)),
|
_ => (text, style_computer.style_primitive(value)),
|
||||||
|
@ -170,11 +170,9 @@ fn record_lookup_value(item: &Value, header: &str) -> Value {
|
|||||||
span: NuSpan::unknown(),
|
span: NuSpan::unknown(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = item.clone().follow_cell_path(&[path], false, false);
|
item.clone()
|
||||||
match value {
|
.follow_cell_path(&[path], false, false)
|
||||||
Ok(value) => value,
|
.unwrap_or_else(|_| item.clone())
|
||||||
Err(_) => item.clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
item => item.clone(),
|
item => item.clone(),
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,16 @@ impl UIEvents {
|
|||||||
pub fn next(&self) -> Result<Option<KeyEvent>> {
|
pub fn next(&self) -> Result<Option<KeyEvent>> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
match poll(self.tick_rate) {
|
match poll(self.tick_rate) {
|
||||||
Ok(true) => match read()? {
|
Ok(true) => {
|
||||||
Event::Key(event) => Ok(Some(event)),
|
if let Event::Key(event) = read()? {
|
||||||
_ => {
|
Ok(Some(event))
|
||||||
|
} else {
|
||||||
let time_spent = now.elapsed();
|
let time_spent = now.elapsed();
|
||||||
let rest = self.tick_rate - time_spent;
|
let rest = self.tick_rate - time_spent;
|
||||||
|
|
||||||
Self { tick_rate: rest }.next()
|
Self { tick_rate: rest }.next()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Ok(false) => Ok(None),
|
Ok(false) => Ok(None),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
|
@ -160,10 +160,7 @@ where
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let amount = match cfg.length {
|
let amount = cfg.length.unwrap_or_else(|| source.as_ref().len());
|
||||||
Some(len) => len,
|
|
||||||
None => source.as_ref().len(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let skip = cfg.skip.unwrap_or(0);
|
let skip = cfg.skip.unwrap_or(0);
|
||||||
|
|
||||||
@ -239,10 +236,7 @@ where
|
|||||||
write!(writer, " ")?;
|
write!(writer, " ")?;
|
||||||
for x in row {
|
for x in row {
|
||||||
let (style, a_char) = categorize_byte(x);
|
let (style, a_char) = categorize_byte(x);
|
||||||
let replacement_char = match a_char {
|
let replacement_char = a_char.unwrap_or(*x as char);
|
||||||
Some(c) => c,
|
|
||||||
None => *x as char,
|
|
||||||
};
|
|
||||||
if use_color {
|
if use_color {
|
||||||
write!(
|
write!(
|
||||||
writer,
|
writer,
|
||||||
|
@ -1119,34 +1119,22 @@ impl Value {
|
|||||||
// Reconstruct
|
// Reconstruct
|
||||||
let mut hook_cols = vec![];
|
let mut hook_cols = vec![];
|
||||||
let mut hook_vals = vec![];
|
let mut hook_vals = vec![];
|
||||||
match &config.hooks.pre_prompt {
|
if let Some(ref value) = config.hooks.pre_prompt {
|
||||||
Some(v) => {
|
hook_cols.push("pre_prompt".into());
|
||||||
hook_cols.push("pre_prompt".into());
|
hook_vals.push(value.clone());
|
||||||
hook_vals.push(v.clone());
|
}
|
||||||
}
|
if let Some(ref value) = config.hooks.pre_execution {
|
||||||
None => (),
|
hook_cols.push("pre_execution".into());
|
||||||
};
|
hook_vals.push(value.clone());
|
||||||
match &config.hooks.pre_execution {
|
}
|
||||||
Some(v) => {
|
if let Some(ref value) = config.hooks.env_change {
|
||||||
hook_cols.push("pre_execution".into());
|
hook_cols.push("env_change".into());
|
||||||
hook_vals.push(v.clone());
|
hook_vals.push(value.clone());
|
||||||
}
|
}
|
||||||
None => (),
|
if let Some(ref value) = config.hooks.display_output {
|
||||||
};
|
hook_cols.push("display_output".into());
|
||||||
match &config.hooks.env_change {
|
hook_vals.push(value.clone());
|
||||||
Some(v) => {
|
}
|
||||||
hook_cols.push("env_change".into());
|
|
||||||
hook_vals.push(v.clone());
|
|
||||||
}
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
match &config.hooks.display_output {
|
|
||||||
Some(v) => {
|
|
||||||
hook_cols.push("display_output".into());
|
|
||||||
hook_vals.push(v.clone());
|
|
||||||
}
|
|
||||||
None => (),
|
|
||||||
};
|
|
||||||
vals.push(Value::Record {
|
vals.push(Value::Record {
|
||||||
cols: hook_cols,
|
cols: hook_cols,
|
||||||
vals: hook_vals,
|
vals: hook_vals,
|
||||||
@ -1496,8 +1484,8 @@ fn try_parse_trim_strategy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
||||||
match value.as_string() {
|
if let Ok(value) = value.as_string() {
|
||||||
Ok(value) => match value.to_lowercase().as_str() {
|
match value.to_lowercase().as_str() {
|
||||||
"wrapping" => {
|
"wrapping" => {
|
||||||
return Some(TrimStrategy::Wrap {
|
return Some(TrimStrategy::Wrap {
|
||||||
try_to_keep_words: false,
|
try_to_keep_words: false,
|
||||||
@ -1505,8 +1493,9 @@ fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
|||||||
}
|
}
|
||||||
"truncating" => return Some(TrimStrategy::Truncate { suffix: None }),
|
"truncating" => return Some(TrimStrategy::Truncate { suffix: None }),
|
||||||
_ => eprintln!("unrecognized $config.table.trim.methodology value; expected either 'truncating' or 'wrapping'"),
|
_ => eprintln!("unrecognized $config.table.trim.methodology value; expected either 'truncating' or 'wrapping'"),
|
||||||
},
|
}
|
||||||
Err(_) => eprintln!("$env.config.table.trim.methodology is not a string"),
|
} else {
|
||||||
|
eprintln!("$env.config.table.trim.methodology is not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@ -1548,18 +1537,11 @@ fn create_hooks(value: &Value) -> Result<Hooks, ShellError> {
|
|||||||
|
|
||||||
Ok(hooks)
|
Ok(hooks)
|
||||||
}
|
}
|
||||||
v => match v.span() {
|
v => Err(ShellError::UnsupportedConfigValue(
|
||||||
Ok(span) => Err(ShellError::UnsupportedConfigValue(
|
"record for 'hooks' config".into(),
|
||||||
"record for 'hooks' config".into(),
|
"non-record value".into(),
|
||||||
"non-record value".into(),
|
v.span().unwrap_or_else(|_| Span::unknown()),
|
||||||
span,
|
)),
|
||||||
)),
|
|
||||||
_ => Err(ShellError::UnsupportedConfigValue(
|
|
||||||
"record for 'hooks' config".into(),
|
|
||||||
"non-record value".into(),
|
|
||||||
Span::unknown(),
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,15 +484,17 @@ impl EngineState {
|
|||||||
serde_json::to_string_pretty(&decl.signature())
|
serde_json::to_string_pretty(&decl.signature())
|
||||||
.map(|signature| {
|
.map(|signature| {
|
||||||
// Extracting the possible path to the shell used to load the plugin
|
// Extracting the possible path to the shell used to load the plugin
|
||||||
let shell_str = match shell {
|
let shell_str = shell
|
||||||
Some(path) => format!(
|
.as_ref()
|
||||||
"-s {}",
|
.map(|path| {
|
||||||
path.to_str().expect(
|
format!(
|
||||||
"shell path was checked during registration as a str"
|
"-s {}",
|
||||||
|
path.to_str().expect(
|
||||||
|
"shell path was checked during registration as a str"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
),
|
})
|
||||||
None => "".into(),
|
.unwrap_or_default();
|
||||||
};
|
|
||||||
|
|
||||||
// Each signature is stored in the plugin file with the shell and signature
|
// Each signature is stored in the plugin file with the shell and signature
|
||||||
// This information will be used when loading the plugin
|
// This information will be used when loading the plugin
|
||||||
@ -1020,9 +1022,10 @@ impl TypeScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_type(&mut self, input: Type) {
|
pub fn add_type(&mut self, input: Type) {
|
||||||
match self.outputs.last_mut() {
|
if let Some(v) = self.outputs.last_mut() {
|
||||||
Some(v) => v.push(input),
|
v.push(input)
|
||||||
None => self.outputs.push(vec![input]),
|
} else {
|
||||||
|
self.outputs.push(vec![input])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +225,10 @@ impl OverlayFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_decl(&self, name: &[u8], input: &Type) -> Option<DeclId> {
|
pub fn get_decl(&self, name: &[u8], input: &Type) -> Option<DeclId> {
|
||||||
match self.decls.get(&(name, input) as &dyn DeclKey) {
|
if let Some(decl) = self.decls.get(&(name, input) as &dyn DeclKey) {
|
||||||
Some(decl) => Some(*decl),
|
Some(*decl)
|
||||||
None => self.decls.get(&(name, &Type::Any) as &dyn DeclKey).cloned(),
|
} else {
|
||||||
|
self.decls.get(&(name, &Type::Any) as &dyn DeclKey).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,11 +157,12 @@ fn find_best_match_for_name_impl<'c>(
|
|||||||
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
|
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
|
||||||
let mut best = None;
|
let mut best = None;
|
||||||
for c in candidates {
|
for c in candidates {
|
||||||
match if use_substring_score {
|
let lev_dist = if use_substring_score {
|
||||||
lev_distance_with_substrings(lookup, c, dist)
|
lev_distance_with_substrings(lookup, c, dist)
|
||||||
} else {
|
} else {
|
||||||
lev_distance(lookup, c, dist)
|
lev_distance(lookup, c, dist)
|
||||||
} {
|
};
|
||||||
|
match lev_dist {
|
||||||
Some(0) => return Some(*c),
|
Some(0) => return Some(*c),
|
||||||
Some(d) => {
|
Some(d) => {
|
||||||
dist = d - 1;
|
dist = d - 1;
|
||||||
|
@ -266,13 +266,7 @@ impl PipelineData {
|
|||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
for val in s {
|
for val in s {
|
||||||
match val {
|
output.push_str(&val?.as_string()?);
|
||||||
Ok(val) => match val.as_string() {
|
|
||||||
Ok(s) => output.push_str(&s),
|
|
||||||
Err(err) => return Err(err),
|
|
||||||
},
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if trim_end_newline {
|
if trim_end_newline {
|
||||||
output.truncate(output.trim_end_matches(LINE_ENDING_PATTERN).len());
|
output.truncate(output.trim_end_matches(LINE_ENDING_PATTERN).len());
|
||||||
@ -449,12 +443,10 @@ impl PipelineData {
|
|||||||
.into_pipeline_data(ctrlc))
|
.into_pipeline_data(ctrlc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::Value(Value::Range { val, .. }, ..) => {
|
PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
|
||||||
match val.into_range_iter(ctrlc.clone()) {
|
.into_range_iter(ctrlc.clone())?
|
||||||
Ok(iter) => Ok(iter.flat_map(f).into_pipeline_data(ctrlc)),
|
.flat_map(f)
|
||||||
Err(error) => Err(error),
|
.into_pipeline_data(ctrlc)),
|
||||||
}
|
|
||||||
}
|
|
||||||
PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),
|
PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,10 +550,10 @@ impl PipelineData {
|
|||||||
let stderr = stderr.map(|stderr_stream| {
|
let stderr = stderr.map(|stderr_stream| {
|
||||||
let stderr_ctrlc = stderr_stream.ctrlc.clone();
|
let stderr_ctrlc = stderr_stream.ctrlc.clone();
|
||||||
let stderr_span = stderr_stream.span;
|
let stderr_span = stderr_stream.span;
|
||||||
let stderr_bytes = match stderr_stream.into_bytes() {
|
let stderr_bytes = stderr_stream
|
||||||
Err(_) => vec![],
|
.into_bytes()
|
||||||
Ok(bytes) => bytes.item,
|
.map(|bytes| bytes.item)
|
||||||
};
|
.unwrap_or_default();
|
||||||
RawStream::new(
|
RawStream::new(
|
||||||
Box::new(vec![Ok(stderr_bytes)].into_iter()),
|
Box::new(vec![Ok(stderr_bytes)].into_iter()),
|
||||||
stderr_ctrlc,
|
stderr_ctrlc,
|
||||||
@ -642,20 +634,17 @@ impl PipelineData {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
match engine_state.find_decl("table".as_bytes(), &[]) {
|
if let Some(decl_id) = engine_state.find_decl("table".as_bytes(), &[]) {
|
||||||
Some(decl_id) => {
|
let command = engine_state.get_decl(decl_id);
|
||||||
let command = engine_state.get_decl(decl_id);
|
if command.get_block_id().is_some() {
|
||||||
if command.get_block_id().is_some() {
|
return self.write_all_and_flush(engine_state, config, no_newline, to_stderr);
|
||||||
return self.write_all_and_flush(engine_state, config, no_newline, to_stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
let table = command.run(engine_state, stack, &Call::new(Span::new(0, 0)), self)?;
|
|
||||||
|
|
||||||
table.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let table = command.run(engine_state, stack, &Call::new(Span::new(0, 0)), self)?;
|
||||||
|
|
||||||
|
table.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||||
|
} else {
|
||||||
|
self.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
@ -197,9 +197,6 @@ impl Value {
|
|||||||
Value::Binary { val, .. } => Ok(match std::str::from_utf8(val) {
|
Value::Binary { val, .. } => Ok(match std::str::from_utf8(val) {
|
||||||
Ok(s) => s.to_string(),
|
Ok(s) => s.to_string(),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// println!("{:?}", e);
|
|
||||||
// println!("bytes: {}", pretty_hex::pretty_hex(&val));
|
|
||||||
// panic!("let's see it");
|
|
||||||
return Err(ShellError::CantConvert(
|
return Err(ShellError::CantConvert(
|
||||||
"string".into(),
|
"string".into(),
|
||||||
"binary".into(),
|
"binary".into(),
|
||||||
@ -495,9 +492,10 @@ impl Value {
|
|||||||
separator: &str,
|
separator: &str,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<String, ShellError> {
|
) -> Result<String, ShellError> {
|
||||||
match self {
|
if let Value::Error { error } = self {
|
||||||
Value::Error { error } => Err(error.to_owned()),
|
Err(error.to_owned())
|
||||||
_ => Ok(self.into_string(separator, config)),
|
} else {
|
||||||
|
Ok(self.into_string(separator, config))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1813,10 +1811,13 @@ impl PartialOrd for Value {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::LazyRecord { val, .. } => match val.collect() {
|
Value::LazyRecord { val, .. } => {
|
||||||
Ok(rhs) => self.partial_cmp(&rhs),
|
if let Ok(rhs) = val.collect() {
|
||||||
Err(_) => None,
|
self.partial_cmp(&rhs)
|
||||||
},
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
Value::List { .. } => Some(Ordering::Less),
|
Value::List { .. } => Some(Ordering::Less),
|
||||||
Value::Block { .. } => Some(Ordering::Less),
|
Value::Block { .. } => Some(Ordering::Less),
|
||||||
Value::Closure { .. } => Some(Ordering::Less),
|
Value::Closure { .. } => Some(Ordering::Less),
|
||||||
@ -1967,10 +1968,13 @@ impl PartialOrd for Value {
|
|||||||
Value::CustomValue { .. } => Some(Ordering::Less),
|
Value::CustomValue { .. } => Some(Ordering::Less),
|
||||||
},
|
},
|
||||||
(Value::CustomValue { val: lhs, .. }, rhs) => lhs.partial_cmp(rhs),
|
(Value::CustomValue { val: lhs, .. }, rhs) => lhs.partial_cmp(rhs),
|
||||||
(Value::LazyRecord { val, .. }, rhs) => match val.collect() {
|
(Value::LazyRecord { val, .. }, rhs) => {
|
||||||
Ok(val) => val.partial_cmp(rhs),
|
if let Ok(val) = val.collect() {
|
||||||
Err(_) => None,
|
val.partial_cmp(rhs)
|
||||||
},
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2012,13 +2016,14 @@ impl Value {
|
|||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||||
match lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) {
|
if let Some(val) = lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) {
|
||||||
Some(val) => Ok(Value::Date { val, span }),
|
Ok(Value::Date { val, span })
|
||||||
_ => Err(ShellError::OperatorOverflow(
|
} else {
|
||||||
|
Err(ShellError::OperatorOverflow(
|
||||||
"addition operation overflowed".into(),
|
"addition operation overflowed".into(),
|
||||||
span,
|
span,
|
||||||
"".into(),
|
"".into(),
|
||||||
)),
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||||
@ -2114,13 +2119,14 @@ impl Value {
|
|||||||
(Value::Date { val: lhs, .. }, Value::Date { val: rhs, .. }) => {
|
(Value::Date { val: lhs, .. }, Value::Date { val: rhs, .. }) => {
|
||||||
let result = lhs.signed_duration_since(*rhs);
|
let result = lhs.signed_duration_since(*rhs);
|
||||||
|
|
||||||
match result.num_nanoseconds() {
|
if let Some(v) = result.num_nanoseconds() {
|
||||||
Some(v) => Ok(Value::Duration { val: v, span }),
|
Ok(Value::Duration { val: v, span })
|
||||||
None => Err(ShellError::OperatorOverflow(
|
} else {
|
||||||
|
Err(ShellError::OperatorOverflow(
|
||||||
"subtraction operation overflowed".into(),
|
"subtraction operation overflowed".into(),
|
||||||
span,
|
span,
|
||||||
"".into(),
|
"".into(),
|
||||||
)),
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||||
@ -2552,18 +2558,19 @@ impl Value {
|
|||||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Ok(Value::Bool {
|
||||||
val: matches!(ordering, Ordering::Less),
|
val: matches!(ordering, Ordering::Less),
|
||||||
span,
|
span,
|
||||||
}),
|
})
|
||||||
None => Err(ShellError::OperatorMismatch {
|
} else {
|
||||||
|
Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span()?,
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span()?,
|
rhs_span: rhs.span()?,
|
||||||
}),
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2584,19 +2591,18 @@ impl Value {
|
|||||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
self.partial_cmp(rhs)
|
||||||
Some(ordering) => Ok(Value::Bool {
|
.map(|ordering| Value::Bool {
|
||||||
val: matches!(ordering, Ordering::Less | Ordering::Equal),
|
val: matches!(ordering, Ordering::Less | Ordering::Equal),
|
||||||
span,
|
span,
|
||||||
}),
|
})
|
||||||
None => Err(ShellError::OperatorMismatch {
|
.ok_or(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span()?,
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span()?,
|
rhs_span: rhs.span()?,
|
||||||
}),
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||||
@ -2616,19 +2622,18 @@ impl Value {
|
|||||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
self.partial_cmp(rhs)
|
||||||
Some(ordering) => Ok(Value::Bool {
|
.map(|ordering| Value::Bool {
|
||||||
val: matches!(ordering, Ordering::Greater),
|
val: matches!(ordering, Ordering::Greater),
|
||||||
span,
|
span,
|
||||||
}),
|
})
|
||||||
None => Err(ShellError::OperatorMismatch {
|
.ok_or(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span()?,
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span()?,
|
rhs_span: rhs.span()?,
|
||||||
}),
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||||
@ -2668,12 +2673,13 @@ impl Value {
|
|||||||
return lhs.operation(*span, Operator::Comparison(Comparison::Equal), op, rhs);
|
return lhs.operation(*span, Operator::Comparison(Comparison::Equal), op, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Ok(Value::Bool {
|
||||||
val: matches!(ordering, Ordering::Equal),
|
val: matches!(ordering, Ordering::Equal),
|
||||||
span,
|
span,
|
||||||
}),
|
})
|
||||||
None => match (self, rhs) {
|
} else {
|
||||||
|
match (self, rhs) {
|
||||||
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
||||||
Ok(Value::Bool { val: false, span })
|
Ok(Value::Bool { val: false, span })
|
||||||
}
|
}
|
||||||
@ -2684,7 +2690,7 @@ impl Value {
|
|||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span()?,
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2693,12 +2699,13 @@ impl Value {
|
|||||||
return lhs.operation(*span, Operator::Comparison(Comparison::NotEqual), op, rhs);
|
return lhs.operation(*span, Operator::Comparison(Comparison::NotEqual), op, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Ok(Value::Bool {
|
||||||
val: !matches!(ordering, Ordering::Equal),
|
val: !matches!(ordering, Ordering::Equal),
|
||||||
span,
|
span,
|
||||||
}),
|
})
|
||||||
None => match (self, rhs) {
|
} else {
|
||||||
|
match (self, rhs) {
|
||||||
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
||||||
Ok(Value::Bool { val: true, span })
|
Ok(Value::Bool { val: true, span })
|
||||||
}
|
}
|
||||||
@ -2709,7 +2716,7 @@ impl Value {
|
|||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span()?,
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2844,9 +2851,10 @@ impl Value {
|
|||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
let is_match = match engine_state.regex_cache.try_lock() {
|
let is_match = match engine_state.regex_cache.try_lock() {
|
||||||
Ok(mut cache) => match cache.get(rhs) {
|
Ok(mut cache) => {
|
||||||
Some(regex) => regex.is_match(lhs),
|
if let Some(regex) = cache.get(rhs) {
|
||||||
None => {
|
regex.is_match(lhs)
|
||||||
|
} else {
|
||||||
let regex = Regex::new(rhs).map_err(|e| {
|
let regex = Regex::new(rhs).map_err(|e| {
|
||||||
ShellError::UnsupportedInput(
|
ShellError::UnsupportedInput(
|
||||||
format!("{e}"),
|
format!("{e}"),
|
||||||
@ -2859,7 +2867,7 @@ impl Value {
|
|||||||
cache.put(rhs.clone(), regex);
|
cache.put(rhs.clone(), regex);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let regex = Regex::new(rhs).map_err(|e| {
|
let regex = Regex::new(rhs).map_err(|e| {
|
||||||
ShellError::UnsupportedInput(
|
ShellError::UnsupportedInput(
|
||||||
|
@ -84,28 +84,24 @@ impl Iterator for RawStream {
|
|||||||
|
|
||||||
// If we know we're already binary, just output that
|
// If we know we're already binary, just output that
|
||||||
if self.is_binary {
|
if self.is_binary {
|
||||||
match self.stream.next() {
|
self.stream.next().map(|buffer| {
|
||||||
Some(buffer) => match buffer {
|
buffer.map(|mut v| {
|
||||||
Ok(mut v) => {
|
if !self.leftover.is_empty() {
|
||||||
if !self.leftover.is_empty() {
|
for b in self.leftover.drain(..).rev() {
|
||||||
while let Some(b) = self.leftover.pop() {
|
v.insert(0, b);
|
||||||
v.insert(0, b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(Ok(Value::Binary {
|
|
||||||
val: v,
|
|
||||||
span: self.span,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
Err(e) => Some(Err(e)),
|
Value::Binary {
|
||||||
},
|
val: v,
|
||||||
None => None,
|
span: self.span,
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// We *may* be text. We're only going to try utf-8. Other decodings
|
// We *may* be text. We're only going to try utf-8. Other decodings
|
||||||
// needs to be taken as binary first, then passed through `decode`.
|
// needs to be taken as binary first, then passed through `decode`.
|
||||||
match self.stream.next() {
|
if let Some(buffer) = self.stream.next() {
|
||||||
Some(buffer) => match buffer {
|
match buffer {
|
||||||
Ok(mut v) => {
|
Ok(mut v) => {
|
||||||
if !self.leftover.is_empty() {
|
if !self.leftover.is_empty() {
|
||||||
while let Some(b) = self.leftover.pop() {
|
while let Some(b) = self.leftover.pop() {
|
||||||
@ -164,20 +160,17 @@ impl Iterator for RawStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
},
|
|
||||||
None => {
|
|
||||||
if !self.leftover.is_empty() {
|
|
||||||
let output = Ok(Value::Binary {
|
|
||||||
val: self.leftover.clone(),
|
|
||||||
span: self.span,
|
|
||||||
});
|
|
||||||
self.leftover.clear();
|
|
||||||
|
|
||||||
Some(output)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if !self.leftover.is_empty() {
|
||||||
|
let output = Ok(Value::Binary {
|
||||||
|
val: self.leftover.clone(),
|
||||||
|
span: self.span,
|
||||||
|
});
|
||||||
|
self.leftover.clear();
|
||||||
|
|
||||||
|
Some(output)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,9 @@ fn main() {
|
|||||||
target_os = "windows"
|
target_os = "windows"
|
||||||
))]
|
))]
|
||||||
{
|
{
|
||||||
let cores = match std::thread::available_parallelism() {
|
let cores = std::thread::available_parallelism()
|
||||||
Ok(p) => p.get(),
|
.map(|p| p.get())
|
||||||
Err(_) => 1usize,
|
.unwrap_or(1);
|
||||||
};
|
|
||||||
for run in 1..=10 {
|
for run in 1..=10 {
|
||||||
for proc in nu_system::collect_proc(std::time::Duration::from_millis(100), false) {
|
for proc in nu_system::collect_proc(std::time::Duration::from_millis(100), false) {
|
||||||
if proc.cpu_usage() > 0.00001 {
|
if proc.cpu_usage() > 0.00001 {
|
||||||
|
@ -12,10 +12,7 @@ pub enum ProcessTask {
|
|||||||
impl ProcessTask {
|
impl ProcessTask {
|
||||||
pub fn stat(&self) -> Result<Stat, ProcError> {
|
pub fn stat(&self) -> Result<Stat, ProcError> {
|
||||||
match self {
|
match self {
|
||||||
ProcessTask::Process(x) => match x.stat() {
|
ProcessTask::Process(x) => x.stat(),
|
||||||
Ok(it) => Ok(it),
|
|
||||||
Err(err) => Err(err),
|
|
||||||
},
|
|
||||||
ProcessTask::Task { stat: x, owner: _ } => Ok(*x.clone()),
|
ProcessTask::Task { stat: x, owner: _ } => Ok(*x.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,13 +33,7 @@ impl ProcessTask {
|
|||||||
|
|
||||||
pub fn fd(&self) -> Result<Vec<FDInfo>, ProcError> {
|
pub fn fd(&self) -> Result<Vec<FDInfo>, ProcError> {
|
||||||
match self {
|
match self {
|
||||||
ProcessTask::Process(x) => {
|
ProcessTask::Process(x) => x.fd()?.collect(),
|
||||||
let fds = match x.fd() {
|
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
};
|
|
||||||
fds.collect()
|
|
||||||
}
|
|
||||||
_ => Err(ProcError::Other("not supported".to_string())),
|
_ => Err(ProcError::Other("not supported".to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,10 +104,7 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
|
|||||||
let curr_status = curr_proc.status().ok();
|
let curr_status = curr_proc.status().ok();
|
||||||
let curr_time = Instant::now();
|
let curr_time = Instant::now();
|
||||||
let interval = curr_time - prev_time;
|
let interval = curr_time - prev_time;
|
||||||
let ppid = match curr_proc.stat() {
|
let ppid = curr_proc.stat().map(|p| p.ppid).unwrap_or_default();
|
||||||
Ok(p) => p.ppid,
|
|
||||||
Err(_) => 0,
|
|
||||||
};
|
|
||||||
let curr_proc = ProcessTask::Process(curr_proc);
|
let curr_proc = ProcessTask::Process(curr_proc);
|
||||||
|
|
||||||
let proc = ProcessInfo {
|
let proc = ProcessInfo {
|
||||||
@ -174,23 +162,25 @@ impl ProcessInfo {
|
|||||||
|
|
||||||
/// Get the status of the process
|
/// Get the status of the process
|
||||||
pub fn status(&self) -> String {
|
pub fn status(&self) -> String {
|
||||||
match self.curr_proc.stat() {
|
if let Ok(p) = self.curr_proc.stat() {
|
||||||
Ok(p) => match p.state {
|
match p.state {
|
||||||
'S' => "Sleeping".into(),
|
'S' => "Sleeping",
|
||||||
'R' => "Running".into(),
|
'R' => "Running",
|
||||||
'D' => "Disk sleep".into(),
|
'D' => "Disk sleep",
|
||||||
'Z' => "Zombie".into(),
|
'Z' => "Zombie",
|
||||||
'T' => "Stopped".into(),
|
'T' => "Stopped",
|
||||||
't' => "Tracing".into(),
|
't' => "Tracing",
|
||||||
'X' => "Dead".into(),
|
'X' => "Dead",
|
||||||
'x' => "Dead".into(),
|
'x' => "Dead",
|
||||||
'K' => "Wakekill".into(),
|
'K' => "Wakekill",
|
||||||
'W' => "Waking".into(),
|
'W' => "Waking",
|
||||||
'P' => "Parked".into(),
|
'P' => "Parked",
|
||||||
_ => "Unknown".into(),
|
_ => "Unknown",
|
||||||
},
|
}
|
||||||
Err(_) => "Unknown".into(),
|
} else {
|
||||||
|
"Unknown"
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CPU usage as a percent of total
|
/// CPU usage as a percent of total
|
||||||
@ -223,9 +213,6 @@ impl ProcessInfo {
|
|||||||
|
|
||||||
/// Virtual memory size in bytes
|
/// Virtual memory size in bytes
|
||||||
pub fn virtual_size(&self) -> u64 {
|
pub fn virtual_size(&self) -> u64 {
|
||||||
match self.curr_proc.stat() {
|
self.curr_proc.stat().map(|p| p.vsize).unwrap_or_default()
|
||||||
Ok(p) => p.vsize,
|
|
||||||
Err(_) => 0u64,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,18 +194,6 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
|
|||||||
all_ok &= thread.is_some();
|
all_ok &= thread.is_some();
|
||||||
|
|
||||||
if all_ok {
|
if all_ok {
|
||||||
// let process_params = unsafe { get_process_params(handle) };
|
|
||||||
// match process_params {
|
|
||||||
// Ok((pp_cmd, pp_env, pp_cwd)) => {
|
|
||||||
// eprintln!(
|
|
||||||
// "cmd: {:?}, env: {:?}, cwd: {:?}",
|
|
||||||
// pp_cmd,
|
|
||||||
// "noop".to_string(),
|
|
||||||
// pp_cwd
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// Err(_) => {}
|
|
||||||
// }
|
|
||||||
let (proc_cmd, proc_env, proc_cwd) = match unsafe { get_process_params(handle) } {
|
let (proc_cmd, proc_env, proc_cwd) = match unsafe { get_process_params(handle) } {
|
||||||
Ok(pp) => (pp.0, pp.1, pp.2),
|
Ok(pp) => (pp.0, pp.1, pp.2),
|
||||||
Err(_) => (vec![], vec![], PathBuf::new()),
|
Err(_) => (vec![], vec![], PathBuf::new()),
|
||||||
@ -733,10 +721,7 @@ fn get_cmd_line_new(handle: HANDLE) -> Vec<String> {
|
|||||||
fn get_cmd_line_old<T: RtlUserProcessParameters>(params: &T, handle: HANDLE) -> Vec<String> {
|
fn get_cmd_line_old<T: RtlUserProcessParameters>(params: &T, handle: HANDLE) -> Vec<String> {
|
||||||
match params.get_cmdline(handle) {
|
match params.get_cmdline(handle) {
|
||||||
Ok(buffer) => unsafe { get_cmdline_from_buffer(buffer.as_ptr()) },
|
Ok(buffer) => unsafe { get_cmdline_from_buffer(buffer.as_ptr()) },
|
||||||
Err(_e) => {
|
Err(_e) => Vec::new(),
|
||||||
// sysinfo_debug!("get_cmd_line_old failed to get data: {}", _e);
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,10 +750,7 @@ fn get_proc_env<T: RtlUserProcessParameters>(params: &T, handle: HANDLE) -> Vec<
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Err(_e) => {
|
Err(_e) => Vec::new(),
|
||||||
// sysinfo_debug!("get_proc_env failed to get data: {}", _e);
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +67,16 @@ fn nu_protocol_value_to_json(
|
|||||||
let mut used_cols: Option<&[String]> = None;
|
let mut used_cols: Option<&[String]> = None;
|
||||||
for val in &vals {
|
for val in &vals {
|
||||||
match val {
|
match val {
|
||||||
Value::Record { cols, .. } => match &used_cols {
|
Value::Record { cols, .. } => {
|
||||||
Some(_cols) => {
|
if let Some(_cols) = &used_cols {
|
||||||
if _cols != cols {
|
if _cols != cols {
|
||||||
used_cols = None;
|
used_cols = None;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
used_cols = Some(cols)
|
||||||
}
|
}
|
||||||
None => used_cols = Some(cols),
|
}
|
||||||
},
|
|
||||||
_ => {
|
_ => {
|
||||||
used_cols = None;
|
used_cols = None;
|
||||||
break;
|
break;
|
||||||
|
@ -574,15 +574,14 @@ impl Peaker for PriorityMax {
|
|||||||
|
|
||||||
fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
|
fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
|
||||||
let col = (0..widths.len()).rev().max_by_key(|&i| widths[i]);
|
let col = (0..widths.len()).rev().max_by_key(|&i| widths[i]);
|
||||||
match col {
|
if let Some(col) = col {
|
||||||
Some(col) => {
|
if widths[col] == 0 {
|
||||||
if widths[col] == 0 {
|
None
|
||||||
None
|
} else {
|
||||||
} else {
|
Some(col)
|
||||||
Some(col)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => None,
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,5 @@ pub fn with_locale_override<T>(locale_string: &str, func: fn() -> T) -> T {
|
|||||||
|
|
||||||
result
|
result
|
||||||
};
|
};
|
||||||
|
result.unwrap_or_else(|err| std::panic::resume_unwind(err))
|
||||||
match result {
|
|
||||||
Ok(result) => result,
|
|
||||||
Err(err) => std::panic::resume_unwind(err),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -99,17 +99,14 @@ impl Executable for Director {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let process = match binary
|
let process = binary
|
||||||
.construct()
|
.construct()
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
// .stdin(Stdio::piped())
|
// .stdin(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.arg(format!("-c '{}'", commands))
|
.arg(format!("-c '{}'", commands))
|
||||||
.spawn()
|
.spawn()
|
||||||
{
|
.expect("It should be possible to run tests");
|
||||||
Ok(child) => child,
|
|
||||||
Err(why) => panic!("Can't run test {}", why),
|
|
||||||
};
|
|
||||||
|
|
||||||
process
|
process
|
||||||
.wait_with_output()
|
.wait_with_output()
|
||||||
|
@ -48,10 +48,8 @@ impl CheckerMatchers for Play {
|
|||||||
Some(out) => out,
|
Some(out) => out,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
let actual = match str::from_utf8(actual) {
|
let actual =
|
||||||
Err(..) => return Err(format!("{} was not utf8 encoded", description)),
|
str::from_utf8(actual).map_err(|_| format!("{} was not utf8 encoded", description))?;
|
||||||
Ok(actual) => actual,
|
|
||||||
};
|
|
||||||
|
|
||||||
if actual != *out {
|
if actual != *out {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
@ -9,20 +9,15 @@ pub fn get_system_locale() -> Locale {
|
|||||||
// however Locale::from_name() wants only de so we split and parse it out.
|
// however Locale::from_name() wants only de so we split and parse it out.
|
||||||
let locale_string = locale_string.replace('_', "-"); // en_AU -> en-AU
|
let locale_string = locale_string.replace('_', "-"); // en_AU -> en-AU
|
||||||
|
|
||||||
match Locale::from_name(&locale_string) {
|
Locale::from_name(&locale_string).unwrap_or_else(|_| {
|
||||||
Ok(loc) => loc,
|
let all = num_format::Locale::available_names();
|
||||||
_ => {
|
let locale_prefix = &locale_string.split('-').collect::<Vec<&str>>();
|
||||||
let all = num_format::Locale::available_names();
|
if all.contains(&locale_prefix[0]) {
|
||||||
let locale_prefix = &locale_string.split('-').collect::<Vec<&str>>();
|
Locale::from_name(locale_prefix[0]).unwrap_or(Locale::en)
|
||||||
if all.contains(&locale_prefix[0]) {
|
} else {
|
||||||
// eprintln!("Found alternate: {}", &locale_prefix[0]);
|
Locale::en
|
||||||
Locale::from_name(locale_prefix[0]).unwrap_or(Locale::en)
|
|
||||||
} else {
|
|
||||||
// eprintln!("Unable to find matching locale. Defaulting to en-US");
|
|
||||||
Locale::en
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
File diff suppressed because one or more lines are too long
@ -22,15 +22,18 @@ impl CoolCustomValue {
|
|||||||
|
|
||||||
pub fn try_from_value(value: &Value) -> Result<Self, ShellError> {
|
pub fn try_from_value(value: &Value) -> Result<Self, ShellError> {
|
||||||
match value {
|
match value {
|
||||||
Value::CustomValue { val, span } => match val.as_any().downcast_ref::<Self>() {
|
Value::CustomValue { val, span } => {
|
||||||
Some(cool) => Ok(cool.clone()),
|
if let Some(cool) = val.as_any().downcast_ref::<Self>() {
|
||||||
None => Err(ShellError::CantConvert(
|
Ok(cool.clone())
|
||||||
"cool".into(),
|
} else {
|
||||||
"non-cool".into(),
|
Err(ShellError::CantConvert(
|
||||||
*span,
|
"cool".into(),
|
||||||
None,
|
"non-cool".into(),
|
||||||
)),
|
*span,
|
||||||
},
|
None,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
x => Err(ShellError::CantConvert(
|
x => Err(ShellError::CantConvert(
|
||||||
"cool".into(),
|
"cool".into(),
|
||||||
x.get_type().to_string(),
|
x.get_type().to_string(),
|
||||||
|
@ -35,14 +35,16 @@ impl Example {
|
|||||||
eprintln!("flag: {:}", flag);
|
eprintln!("flag: {:}", flag);
|
||||||
eprintln!("rest: {:?}", rest);
|
eprintln!("rest: {:?}", rest);
|
||||||
|
|
||||||
match opt {
|
if let Some(v) = opt {
|
||||||
Some(v) => eprintln!("Found optional value opt: {:}", v),
|
eprintln!("Found optional value opt: {:}", v)
|
||||||
None => eprintln!("No optional value found"),
|
} else {
|
||||||
|
eprintln!("No optional value found")
|
||||||
}
|
}
|
||||||
|
|
||||||
match named {
|
if let Some(v) = named {
|
||||||
Some(v) => eprintln!("Named value: {:?}", v),
|
eprintln!("Named value: {:?}", v)
|
||||||
None => eprintln!("No named value found"),
|
} else {
|
||||||
|
eprintln!("No named value found")
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -79,24 +79,18 @@ impl GStat {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let metadata = std::fs::metadata(&a_path.item).map_err(|e| LabeledError {
|
||||||
let metadata = match std::fs::metadata(&a_path.item) {
|
label: "error with metadata".to_string(),
|
||||||
Ok(md) => md,
|
msg: format!(
|
||||||
Err(e) => {
|
"unable to get metadata for [{}], error: {}",
|
||||||
return Err(LabeledError {
|
&a_path.item, e
|
||||||
label: "error with metadata".to_string(),
|
),
|
||||||
msg: format!(
|
span: if using_input_value {
|
||||||
"unable to get metadata for [{}], error: {}",
|
Some(value.span().expect("unable to get value span"))
|
||||||
&a_path.item, e
|
} else {
|
||||||
),
|
Some(a_path.span)
|
||||||
span: if using_input_value {
|
},
|
||||||
Some(value.span().expect("unable to get value span"))
|
})?;
|
||||||
} else {
|
|
||||||
Some(a_path.span)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This path has to be a directory
|
// This path has to be a directory
|
||||||
if !metadata.is_dir() {
|
if !metadata.is_dir() {
|
||||||
@ -417,25 +411,23 @@ impl Stats {
|
|||||||
/// Read name of the upstream branch
|
/// Read name of the upstream branch
|
||||||
fn read_upstream_name(&mut self, repo: &Repository, branch: &str) {
|
fn read_upstream_name(&mut self, repo: &Repository, branch: &str) {
|
||||||
// First grab branch from the name
|
// First grab branch from the name
|
||||||
self.remote = match repo.find_branch(branch, BranchType::Local) {
|
self.remote = if let Ok(branch) = repo.find_branch(branch, BranchType::Local) {
|
||||||
Ok(branch) => {
|
// Grab the upstream from the branch
|
||||||
// Grab the upstream from the branch
|
if let Ok(upstream) = branch.upstream() {
|
||||||
match branch.upstream() {
|
// While we have the upstream branch, traverse the graph and count
|
||||||
// Grab the name of the upstream if it's valid UTF-8
|
// ahead-behind commits.
|
||||||
Ok(upstream) => {
|
self.read_ahead_behind(repo, &branch, &upstream);
|
||||||
// While we have the upstream branch, traverse the graph and count
|
|
||||||
// ahead-behind commits.
|
|
||||||
self.read_ahead_behind(repo, &branch, &upstream);
|
|
||||||
|
|
||||||
match upstream.name() {
|
if let Ok(Some(name)) = upstream.name() {
|
||||||
Ok(Some(name)) => name.to_string(),
|
name.to_string()
|
||||||
_ => String::new(),
|
} else {
|
||||||
}
|
String::new()
|
||||||
}
|
|
||||||
_ => String::new(),
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
}
|
}
|
||||||
_ => String::new(),
|
} else {
|
||||||
|
String::new()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,10 +43,13 @@ impl Inc {
|
|||||||
|
|
||||||
Value::string(ver.to_string(), head)
|
Value::string(ver.to_string(), head)
|
||||||
}
|
}
|
||||||
Some(Action::Default) | None => match input.parse::<u64>() {
|
Some(Action::Default) | None => {
|
||||||
Ok(v) => Value::string((v + 1).to_string(), head),
|
if let Ok(v) = input.parse::<u64>() {
|
||||||
Err(_) => Value::string(input, head),
|
Value::string((v + 1).to_string(), head)
|
||||||
},
|
} else {
|
||||||
|
Value::string(input, head)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,10 @@ pub fn parse_selector_params(call: &EvaluatedCall, input: &Value) -> Result<Valu
|
|||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
};
|
};
|
||||||
let as_html = call.has_flag("as-html");
|
let as_html = call.has_flag("as-html");
|
||||||
let attribute: String = match call.get_flag("attribute")? {
|
let attribute = call.get_flag("attribute")?.unwrap_or_default();
|
||||||
Some(a) => a,
|
let as_table: Value = call
|
||||||
None => "".to_string(),
|
.get_flag("as-table")?
|
||||||
};
|
.unwrap_or_else(|| Value::nothing(head));
|
||||||
let as_table: Value = match call.get_flag("as-table")? {
|
|
||||||
Some(v) => v,
|
|
||||||
None => Value::nothing(head),
|
|
||||||
};
|
|
||||||
|
|
||||||
let inspect = call.has_flag("inspect");
|
let inspect = call.has_flag("inspect");
|
||||||
|
|
||||||
@ -81,23 +77,22 @@ fn begin_selector_query(input_html: String, selector: Selector, span: Span) -> V
|
|||||||
selector.inspect,
|
selector.inspect,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
|
} else if selector.attribute.is_empty() {
|
||||||
|
execute_selector_query(
|
||||||
|
input_html.as_str(),
|
||||||
|
selector.query.as_str(),
|
||||||
|
selector.as_html,
|
||||||
|
selector.inspect,
|
||||||
|
span,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
match selector.attribute.is_empty() {
|
execute_selector_query_with_attribute(
|
||||||
true => execute_selector_query(
|
input_html.as_str(),
|
||||||
input_html.as_str(),
|
selector.query.as_str(),
|
||||||
selector.query.as_str(),
|
selector.attribute.as_str(),
|
||||||
selector.as_html,
|
selector.inspect,
|
||||||
selector.inspect,
|
span,
|
||||||
span,
|
)
|
||||||
),
|
|
||||||
false => execute_selector_query_with_attribute(
|
|
||||||
input_html.as_str(),
|
|
||||||
selector.query.as_str(),
|
|
||||||
selector.attribute.as_str(),
|
|
||||||
selector.inspect,
|
|
||||||
span,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,17 +104,18 @@ pub fn execute_xpath_query(
|
|||||||
fn build_xpath(xpath_str: &str, span: &Span) -> Result<sxd_xpath::XPath, LabeledError> {
|
fn build_xpath(xpath_str: &str, span: &Span) -> Result<sxd_xpath::XPath, LabeledError> {
|
||||||
let factory = Factory::new();
|
let factory = Factory::new();
|
||||||
|
|
||||||
match factory.build(xpath_str) {
|
if let Ok(xpath) = factory.build(xpath_str) {
|
||||||
Ok(xpath) => xpath.ok_or_else(|| LabeledError {
|
xpath.ok_or_else(|| LabeledError {
|
||||||
label: "invalid xpath query".to_string(),
|
label: "invalid xpath query".to_string(),
|
||||||
msg: "invalid xpath query".to_string(),
|
msg: "invalid xpath query".to_string(),
|
||||||
span: Some(*span),
|
span: Some(*span),
|
||||||
}),
|
})
|
||||||
Err(_) => Err(LabeledError {
|
} else {
|
||||||
|
Err(LabeledError {
|
||||||
label: "expected valid xpath query".to_string(),
|
label: "expected valid xpath query".to_string(),
|
||||||
msg: "expected valid xpath query".to_string(),
|
msg: "expected valid xpath query".to_string(),
|
||||||
span: Some(*span),
|
span: Some(*span),
|
||||||
}),
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +27,11 @@ pub(crate) fn read_config_file(
|
|||||||
let working_set = StateWorkingSet::new(engine_state);
|
let working_set = StateWorkingSet::new(engine_state);
|
||||||
let cwd = working_set.get_cwd();
|
let cwd = working_set.get_cwd();
|
||||||
|
|
||||||
match canonicalize_with(&file.item, cwd) {
|
if let Ok(path) = canonicalize_with(&file.item, cwd) {
|
||||||
Ok(path) => {
|
eval_config_contents(path, engine_state, stack);
|
||||||
eval_config_contents(path, engine_state, stack);
|
} else {
|
||||||
}
|
let e = ParseError::FileNotFound(file.item, file.span);
|
||||||
Err(_) => {
|
report_error(&working_set, &e);
|
||||||
let e = ParseError::FileNotFound(file.item, file.span);
|
|
||||||
report_error(&working_set, &e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if let Some(mut config_path) = nu_path::config_dir() {
|
} else if let Some(mut config_path) = nu_path::config_dir() {
|
||||||
config_path.push(NUSHELL_FOLDER);
|
config_path.push(NUSHELL_FOLDER);
|
||||||
@ -74,9 +71,9 @@ pub(crate) fn read_config_file(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match answer.to_lowercase().trim() {
|
match answer.to_lowercase().trim() {
|
||||||
"y" | "" => match File::create(&config_path) {
|
"y" | "" => {
|
||||||
Ok(mut output) => match write!(output, "{}", config_file) {
|
if let Ok(mut output) = File::create(&config_path) {
|
||||||
Ok(_) => {
|
if write!(output, "{}", config_file).is_ok() {
|
||||||
let config_type = if is_env_config {
|
let config_type = if is_env_config {
|
||||||
"Environment config"
|
"Environment config"
|
||||||
} else {
|
} else {
|
||||||
@ -87,8 +84,7 @@ pub(crate) fn read_config_file(
|
|||||||
config_type,
|
config_type,
|
||||||
config_path.to_string_lossy()
|
config_path.to_string_lossy()
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
Err(_) => {
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Unable to write to {}, sourcing default file instead",
|
"Unable to write to {}, sourcing default file instead",
|
||||||
config_path.to_string_lossy(),
|
config_path.to_string_lossy(),
|
||||||
@ -96,8 +92,7 @@ pub(crate) fn read_config_file(
|
|||||||
eval_default_config(engine_state, stack, config_file, is_env_config);
|
eval_default_config(engine_state, stack, config_file, is_env_config);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
} else {
|
||||||
Err(_) => {
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Unable to create {}, sourcing default file instead",
|
"Unable to create {}, sourcing default file instead",
|
||||||
config_file
|
config_file
|
||||||
@ -105,7 +100,7 @@ pub(crate) fn read_config_file(
|
|||||||
eval_default_config(engine_state, stack, config_file, is_env_config);
|
eval_default_config(engine_state, stack, config_file, is_env_config);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eval_default_config(engine_state, stack, config_file, is_env_config);
|
eval_default_config(engine_state, stack, config_file, is_env_config);
|
||||||
return;
|
return;
|
||||||
|
@ -52,18 +52,17 @@ pub fn logger(
|
|||||||
|
|
||||||
fn set_write_logger(level: LevelFilter, config: Config, path: &Path) -> Result<(), SetLoggerError> {
|
fn set_write_logger(level: LevelFilter, config: Config, path: &Path) -> Result<(), SetLoggerError> {
|
||||||
// Use TermLogger instead if WriteLogger is not available
|
// Use TermLogger instead if WriteLogger is not available
|
||||||
match File::create(path) {
|
if let Ok(file) = File::create(path) {
|
||||||
Ok(file) => WriteLogger::init(level, config, file),
|
WriteLogger::init(level, config, file)
|
||||||
Err(_) => {
|
} else {
|
||||||
let default_logger =
|
let default_logger =
|
||||||
TermLogger::init(level, config, TerminalMode::Stderr, ColorChoice::Auto);
|
TermLogger::init(level, config, TerminalMode::Stderr, ColorChoice::Auto);
|
||||||
|
|
||||||
if default_logger.is_ok() {
|
if default_logger.is_ok() {
|
||||||
log::warn!("failed to init WriteLogger, use TermLogger instead");
|
log::warn!("failed to init WriteLogger, use TermLogger instead");
|
||||||
}
|
|
||||||
|
|
||||||
default_logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_logger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,12 +154,8 @@ pub fn nu_repl() {
|
|||||||
let mut last_output = String::new();
|
let mut last_output = String::new();
|
||||||
|
|
||||||
for (i, line) in source_lines.iter().enumerate() {
|
for (i, line) in source_lines.iter().enumerate() {
|
||||||
let cwd = match nu_engine::env::current_dir(&engine_state, &stack) {
|
let cwd = nu_engine::env::current_dir(&engine_state, &stack)
|
||||||
Ok(d) => d,
|
.unwrap_or_else(|err| outcome_err(&engine_state, &err));
|
||||||
Err(err) => {
|
|
||||||
outcome_err(&engine_state, &err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Before doing anything, merge the environment from the previous REPL iteration into the
|
// Before doing anything, merge the environment from the previous REPL iteration into the
|
||||||
// permanent state.
|
// permanent state.
|
||||||
@ -226,10 +222,9 @@ pub fn nu_repl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cwd) = stack.get_env_var(&engine_state, "PWD") {
|
if let Some(cwd) = stack.get_env_var(&engine_state, "PWD") {
|
||||||
let path = match cwd.as_string() {
|
let path = cwd
|
||||||
Ok(p) => p,
|
.as_string()
|
||||||
Err(err) => outcome_err(&engine_state, &err),
|
.unwrap_or_else(|err| outcome_err(&engine_state, &err));
|
||||||
};
|
|
||||||
let _ = std::env::set_current_dir(path);
|
let _ = std::env::set_current_dir(path);
|
||||||
engine_state.add_env_var("PWD".into(), cwd);
|
engine_state.add_env_var("PWD".into(), cwd);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user