toml-config: add input modes
This commit is contained in:
parent
e160aa3406
commit
a57f0036a8
10 changed files with 797 additions and 46 deletions
125
toml-config/src/config/parsers/input_mode.rs
Normal file
125
toml-config/src/config/parsers/input_mode.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
use {
|
||||
crate::{
|
||||
config::{
|
||||
Shortcut,
|
||||
context::Context,
|
||||
extractor::{Extractor, ExtractorError, opt, recover, str, val},
|
||||
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
|
||||
parsers::shortcuts::{ComplexShortcutsParser, ShortcutsParser, ShortcutsParserError},
|
||||
spanned::SpannedErrorExt,
|
||||
},
|
||||
toml::{
|
||||
toml_span::{DespanExt, Span, Spanned},
|
||||
toml_value::Value,
|
||||
},
|
||||
},
|
||||
ahash::{AHashMap, AHashSet},
|
||||
indexmap::IndexMap,
|
||||
std::collections::HashSet,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InputModeParserError {
|
||||
#[error(transparent)]
|
||||
Expected(#[from] UnexpectedDataType),
|
||||
#[error(transparent)]
|
||||
ExtractorError(#[from] ExtractorError),
|
||||
#[error("Could not parse the shortcuts")]
|
||||
ParseShortcuts(#[source] ShortcutsParserError),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InputMode {
|
||||
pub parent: Option<String>,
|
||||
pub shortcuts: Vec<Shortcut>,
|
||||
}
|
||||
|
||||
pub struct InputModesParser<'a>(pub &'a Context<'a>);
|
||||
|
||||
impl Parser for InputModesParser<'_> {
|
||||
type Value = AHashMap<String, InputMode>;
|
||||
type Error = InputModeParserError;
|
||||
const EXPECTED: &'static [DataType] = &[DataType::Table];
|
||||
|
||||
fn parse_table(
|
||||
&mut self,
|
||||
_span: Span,
|
||||
table: &IndexMap<Spanned<String>, Spanned<Value>>,
|
||||
) -> ParseResult<Self> {
|
||||
let mut modes = AHashMap::new();
|
||||
let mut used = AHashSet::new();
|
||||
for (key, value) in table.iter() {
|
||||
let mode = match value.parse(&mut InputModeParser(self.0)) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
"Could not parse input mode {}: {}",
|
||||
key.value,
|
||||
self.0.error(e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
log_used(self.0, &mut used, key);
|
||||
modes.insert(key.value.to_string(), mode);
|
||||
}
|
||||
Ok(modes)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputModeParser<'a>(pub &'a Context<'a>);
|
||||
|
||||
impl Parser for InputModeParser<'_> {
|
||||
type Value = InputMode;
|
||||
type Error = InputModeParserError;
|
||||
const EXPECTED: &'static [DataType] = &[DataType::Table];
|
||||
|
||||
fn parse_table(
|
||||
&mut self,
|
||||
span: Span,
|
||||
table: &IndexMap<Spanned<String>, Spanned<Value>>,
|
||||
) -> ParseResult<Self> {
|
||||
let mut ext = Extractor::new(self.0, span, table);
|
||||
let (parent, shortcuts_val, complex_shortcuts_val) = ext.extract((
|
||||
recover(opt(str("parent"))),
|
||||
opt(val("shortcuts")),
|
||||
opt(val("complex-shortcuts")),
|
||||
))?;
|
||||
let mut used_keys = HashSet::new();
|
||||
let mut shortcuts = vec![];
|
||||
if let Some(value) = shortcuts_val {
|
||||
value
|
||||
.parse(&mut ShortcutsParser {
|
||||
cx: self.0,
|
||||
used_keys: &mut used_keys,
|
||||
shortcuts: &mut shortcuts,
|
||||
})
|
||||
.map_spanned_err(InputModeParserError::ParseShortcuts)?;
|
||||
}
|
||||
if let Some(value) = complex_shortcuts_val {
|
||||
value
|
||||
.parse(&mut ComplexShortcutsParser {
|
||||
cx: self.0,
|
||||
used_keys: &mut used_keys,
|
||||
shortcuts: &mut shortcuts,
|
||||
})
|
||||
.map_spanned_err(InputModeParserError::ParseShortcuts)?;
|
||||
}
|
||||
Ok(InputMode {
|
||||
parent: parent.despan_into(),
|
||||
shortcuts,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn log_used(cx: &Context<'_>, used: &mut AHashSet<Spanned<String>>, key: &Spanned<String>) {
|
||||
if let Some(prev) = used.get(key) {
|
||||
log::warn!(
|
||||
"Duplicate input mode overrides previous definition: {}",
|
||||
cx.error3(key.span)
|
||||
);
|
||||
log::info!("Previous definition here: {}", cx.error3(prev.span));
|
||||
}
|
||||
used.insert(key.clone());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue