mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +02:00
Refactor config updates (#13802)
# Description This PR standardizes updates to the config through a new `UpdateFromValue` trait. For now, this trait is private in case we need to make changes to it. Note that this PR adds some additional `ShellError` cases to create standard error messages for config errors. A follow-up PR will move usages of the old error cases to these new ones. This PR also uses `Type::custom` in lots of places (e.g., for string enums). Not sure if this is something we want to encourage. # User-Facing Changes Should be none.
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
use super::prelude::*;
|
||||
use crate as nu_protocol;
|
||||
use crate::ShellError;
|
||||
|
||||
/// Definition of a parsed hook from the config object
|
||||
#[derive(Clone, Debug, IntoValue, PartialEq, Serialize, Deserialize)]
|
||||
@ -33,36 +32,36 @@ impl Default for Hooks {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the hooks to find the blocks to run when the hooks fire
|
||||
pub(super) fn create_hooks(value: &Value) -> Result<Hooks, ShellError> {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Record { val, .. } => {
|
||||
let mut hooks = Hooks::new();
|
||||
|
||||
for (col, val) in &**val {
|
||||
match col.as_str() {
|
||||
"pre_prompt" => hooks.pre_prompt = Some(val.clone()),
|
||||
"pre_execution" => hooks.pre_execution = Some(val.clone()),
|
||||
"env_change" => hooks.env_change = Some(val.clone()),
|
||||
"display_output" => hooks.display_output = Some(val.clone()),
|
||||
"command_not_found" => hooks.command_not_found = Some(val.clone()),
|
||||
x => {
|
||||
return Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "'pre_prompt', 'pre_execution', 'env_change', 'display_output', 'command_not_found'".into(),
|
||||
value: x.into(),
|
||||
span
|
||||
});
|
||||
}
|
||||
}
|
||||
impl UpdateFromValue for Hooks {
|
||||
fn update<'a>(
|
||||
&mut self,
|
||||
value: &'a Value,
|
||||
path: &mut ConfigPath<'a>,
|
||||
errors: &mut ConfigErrors,
|
||||
) {
|
||||
fn update_option(field: &mut Option<Value>, value: &Value) {
|
||||
if value.is_nothing() {
|
||||
*field = None;
|
||||
} else {
|
||||
*field = Some(value.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let Value::Record { val: record, .. } = value else {
|
||||
errors.type_mismatch(path, Type::record(), value);
|
||||
return;
|
||||
};
|
||||
|
||||
for (col, val) in record.iter() {
|
||||
let path = &mut path.push(col);
|
||||
match col.as_str() {
|
||||
"pre_prompt" => update_option(&mut self.pre_prompt, val),
|
||||
"pre_execution" => update_option(&mut self.pre_execution, val),
|
||||
"env_change" => update_option(&mut self.env_change, val),
|
||||
"display_output" => update_option(&mut self.display_output, val),
|
||||
"command_not_found" => update_option(&mut self.command_not_found, val),
|
||||
_ => errors.unknown_option(path, val),
|
||||
}
|
||||
|
||||
Ok(hooks)
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedConfigValue {
|
||||
expected: "record for 'hooks' config".into(),
|
||||
value: "non-record value".into(),
|
||||
span,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user