nu_protocol/config/
error.rs1use super::ConfigPath;
2use crate::{Config, ConfigError, ConfigWarning, ShellError, ShellWarning, Span, Type, Value};
3
4#[derive(Debug)]
5#[must_use]
6pub(super) struct ConfigErrors<'a> {
7 config: &'a Config,
8 errors: Vec<ConfigError>,
9 warnings: Vec<ConfigWarning>,
10}
11
12impl<'a> ConfigErrors<'a> {
13 pub fn new(config: &'a Config) -> Self {
14 Self {
15 config,
16 errors: Vec::new(),
17 warnings: Vec::new(),
18 }
19 }
20
21 pub fn has_errors(&self) -> bool {
22 !self.errors.is_empty()
23 }
24
25 pub fn has_warnings(&self) -> bool {
26 !self.warnings.is_empty()
27 }
28
29 pub fn error(&mut self, error: ConfigError) {
30 self.errors.push(error);
31 }
32
33 pub fn warn(&mut self, warning: ConfigWarning) {
34 self.warnings.push(warning);
35 }
36
37 pub fn type_mismatch(&mut self, path: &ConfigPath, expected: Type, actual: &Value) {
38 self.error(ConfigError::TypeMismatch {
39 path: path.to_string(),
40 expected,
41 actual: actual.get_type(),
42 span: actual.span(),
43 });
44 }
45
46 pub fn invalid_value(
47 &mut self,
48 path: &ConfigPath,
49 expected: impl Into<String>,
50 actual: &Value,
51 ) {
52 self.error(ConfigError::InvalidValue {
53 path: path.to_string(),
54 valid: expected.into(),
55 actual: if let Ok(str) = actual.as_str() {
56 format!("'{str}'")
57 } else {
58 actual.to_abbreviated_string(self.config)
59 },
60 span: actual.span(),
61 });
62 }
63
64 pub fn missing_column(&mut self, path: &ConfigPath, column: &'static str, span: Span) {
65 self.error(ConfigError::MissingRequiredColumn {
66 path: path.to_string(),
67 column,
68 span,
69 })
70 }
71
72 pub fn unknown_option(&mut self, path: &ConfigPath, value: &Value) {
73 self.error(ConfigError::UnknownOption {
74 path: path.to_string(),
75 span: value.span(),
76 });
77 }
78
79 #[allow(dead_code)]
81 pub fn deprecated_option(&mut self, path: &ConfigPath, suggestion: &'static str, span: Span) {
82 self.error(ConfigError::Deprecated {
83 path: path.to_string(),
84 suggestion,
85 span,
86 });
87 }
88
89 pub fn check(self) -> Result<Option<ShellWarning>, ShellError> {
90 match (self.has_errors(), self.has_warnings()) {
91 (true, _) => Err(ShellError::InvalidConfig {
92 errors: self.errors,
93 }),
94 (false, true) => Ok(Some(ShellWarning::InvalidConfig {
95 warnings: self.warnings,
96 })),
97 (false, false) => Ok(None),
98 }
99 }
100}