1use std::{collections::HashMap, ops::Range, str::CharIndices};
2
3use rpk_common::{
4 keycodes::{
5 key_range::{self, BASIC_0, BASIC_1, BASIC_A},
6 macro_types,
7 },
8 PROTOCOL_VERSION,
9};
10
11use crate::{
12 globals::{
13 self,
14 spec::{GlobalProp, GlobalType},
15 },
16 keycodes::{self, key_code, unshifted_char_code},
17 ConfigError,
18};
19
20type Result<T> = core::result::Result<T, ConfigError>;
21type IndexChar = (usize, char);
22type NameRange = Range<usize>;
23
24const TOO_MANY_RHS: &str = "Only one value may be assigned";
25const TOO_MANY_MULTI_ALIAS_RHS: &str =
26 "Only one value may be assigned to an multi-positioned alias";
27const TOO_MANY_ROWS: &str = "Too many rows";
28const TOO_MANY_COLS: &str = "Too many keys in row";
29const UNKNOWN_ACTION: &str = "Unknown action/keycode";
30const SYNTAX_ERROR: &str = "Syntax error";
31const EOF: &str = "Unexpected end of file";
32
33struct SourceIter<'source> {
34 iter: CharIndices<'source>,
35 current: IndexChar,
36 next: Option<IndexChar>,
37 len: usize,
38}
39impl<'source> SourceIter<'source> {
40 pub fn new(iter: CharIndices<'source>, len: usize) -> Self {
41 Self {
42 iter,
43 current: (usize::MAX, '\0'),
44 next: None,
45 len,
46 }
47 }
48
49 fn put_back(&mut self, item: IndexChar) {
50 assert!(self.next.is_none() && item.0 == self.current.0);
51 self.next = Some(item);
52 }
53
54 fn next(&mut self) -> Option<IndexChar> {
55 let mut in_comment = false;
56 while let Some(item) = self.next.take().or_else(|| self.iter.next()) {
57 match item.1 {
58 '\n' => {}
59 '#' => {
60 in_comment = true;
61 continue;
62 }
63 _ => {
64 if in_comment {
65 continue;
66 }
67 }
68 }
69 self.current = item;
70 return Some(item);
71 }
72 self.current.0 = self.len;
73 None
74 }
75
76 fn find(&mut self, pred: impl Fn(char) -> bool) -> Option<IndexChar> {
77 while let Some(item) = self.next() {
78 if pred(item.1) {
79 return Some(item);
80 }
81 }
82 None
83 }
84
85 fn find_close_paren(&mut self, parens: (char, char)) -> Option<IndexChar> {
86 let mut count = 1;
87 while let Some(item) = self.next() {
88 if item.1 == parens.0 {
89 count += 1;
90 } else if item.1 == parens.1 {
91 if count == 1 {
92 return Some(item);
93 } else {
94 count -= 1;
95 }
96 }
97 }
98 None
99 }
100}
101
102struct Parser<'source> {
103 iter: SourceIter<'source>,
104 config: KeyboardConfig<'source>,
105 mark_idx: usize,
106}
107
108fn non_ws_char(c: char) -> bool {
109 !c.is_whitespace()
110}
111
112fn invalid_seq_char(c: char) -> bool {
113 c.is_whitespace() || matches!(c, '(' | ')')
114}
115
116fn invalid_arg_char(c: char) -> bool {
117 invalid_seq_char(c) || c == ','
118}
119
120fn invalid_section_char(c: char) -> bool {
121 !matches!(c, '-' | '_' | '\\' | '.' | ':') && !c.is_alphanumeric()
122}
123
124pub struct KeyboardConfig<'source> {
125 pub source: &'source str,
126 pub global_map: HashMap<&'source str, GlobalProp>,
127 pub temp_map: HashMap<&'source str, u16>,
128 pub firmware_map: HashMap<&'source str, &'source str>,
129 pub matrix_map: HashMap<String, Vec<u16>>,
130 layers: HashMap<String, ConfigLayer>,
131 macros_names: HashMap<Vec<u16>, u16>,
132 macros: Vec<Macro>,
133 next_layer: u16,
134 pub row_count: u8,
135 pub col_count: u8,
136}
137
138#[derive(Debug)]
139pub struct ConfigLayer {
140 codes: HashMap<u16, u16>,
141 index: u16,
142 suffix: u8,
143}
144
145#[derive(Debug, PartialEq)]
146pub enum Macro {
147 Modifier { keycode: u16, modifiers: u8 },
148 Tap(Vec<u16>),
149 HoldRelease { hold: u16, release: u16 },
150 Hold(Vec<u16>),
151 Release(Vec<u16>),
152 DualAction(u16, u16),
153 TimedDualAction(u16, u16, u16, u16),
154 Delay(u16),
155}
156impl Macro {
157 fn serialize(&self) -> Vec<u16> {
158 match *self {
159 Macro::Modifier { keycode, modifiers } => {
160 vec![(modifiers as u16) << 8, keycode]
161 }
162 Macro::Tap(ref seq) => binary_seq(macro_types::TAP, seq),
163 Macro::HoldRelease { hold, release } => {
164 vec![macro_types::HOLD_RELEASE, hold, release]
165 }
166 Macro::Hold(ref seq) => binary_seq(macro_types::HOLD, seq),
167 Macro::Release(ref seq) => binary_seq(macro_types::RELEASE, seq),
168 Macro::DualAction(tap, hold) => {
169 vec![macro_types::DUAL_ACTION, tap, hold]
170 }
171 Macro::TimedDualAction(tap, hold, time1, time2) => {
172 if time2 == u16::MAX {
173 vec![macro_types::DUAL_ACTION, tap, hold, time1]
174 } else {
175 vec![macro_types::DUAL_ACTION, tap, hold, time1, time2]
176 }
177 }
178 Macro::Delay(n) => {
179 vec![macro_types::DELAY, n]
180 }
181 }
182 }
183}
184
185fn binary_seq(id: u16, seq: &[u16]) -> Vec<u16> {
186 let mut result = Vec::with_capacity(seq.len() + 1);
187 result.push(id);
188 result.extend_from_slice(seq);
189 result
190}
191
192impl<'source> Parser<'source> {
193 fn new(source: &'source str) -> Self {
194 Self {
195 iter: SourceIter::new(source.char_indices(), source.len()),
196 config: KeyboardConfig::new(source),
197 mark_idx: 0,
198 }
199 }
200
201 fn parse_sections(&mut self) -> Result<()> {
202 self.config.scan_layer_names()?;
203 loop {
204 match self.next_non_ws() {
205 None => return Ok(()),
206 Some(start) => {
207 if start.1 == '[' {
208 self.mark_start();
209 let maybe_tag_end = self
210 .iter
211 .find(|c| matches!(c, ']' | ':' | '.') || invalid_section_char(c));
212 if let Some(tag_end) = maybe_tag_end {
213 let maybe_end = match tag_end.1 {
214 ':' | '.' => {
215 self.iter.find(|c| c == ']' || invalid_section_char(c))
216 }
217 _ => maybe_tag_end,
218 };
219 if let Some(end) = maybe_end {
220 let tag_name = &self.config.source[start.0 + 1..tag_end.0];
221 match tag_name {
222 "global" => self.parse_global(tag_end.0 + 1..end.0)?,
223 "matrix" => self.parse_matrix()?,
224 "firmware" => {
225 self.assert_no_suffix(tag_end.0, end.0)?;
226 self.parse_firmware()?
227 }
228 "aliases" => {
229 self.assert_no_suffix(tag_end.0, end.0)?;
230 self.parse_aliases()?
231 }
232 _ => self.parse_layer(tag_name)?,
233 }
234 continue;
235 }
236 }
237
238 return Err(ConfigError::new("missing ']'".into(), start.0..start.0 + 1));
239 } else {
240 return Err(ConfigError::new(
241 "expected '['".into(),
242 start.0..start.0 + 1,
243 ));
244 }
245 }
246 }
247 }
248 }
249
250 fn parse_global(&mut self, suffix: NameRange) -> Result<()> {
251 if suffix.start < suffix.end {
252 let name = self.name(&suffix);
253 let (name, field) = name.split_once('.').unwrap_or((name, ""));
254
255 match self.config.take_global(name) {
256 Ok(mut g) => {
257 while let Some(pos) = self.skip_whitespace() {
258 if pos.1 == '[' {
259 break;
260 }
261 match self.parse_assignment()? {
262 None => return Ok(()),
263 Some((left, right)) => {
264 let eol = self
265 .iter
266 .find(|c| c == '\n')
267 .unwrap_or((self.config.source.len(), '\0'));
268 if let Err(err) = g.set_sub_field(
269 field,
270 self.name(&left),
271 self.name(&(right.start..eol.0)),
272 ) {
273 return Err(error_span(err, left.start..eol.0));
274 }
275 }
276 }
277 }
278 self.config.insert_global(name, g);
279
280 return Ok(());
281 }
282 Err(err) => return Err(error_span(err.message, suffix)),
283 }
284 }
285
286 while let Some(pos) = self.skip_whitespace() {
287 if pos.1 == '[' {
288 return Ok(());
289 }
290 match self.parse_assignment()? {
291 None => return Ok(()),
292 Some((left, right)) => {
293 self.assign_global(&left, &right)?;
294 self.assert_no_more_values(TOO_MANY_RHS)?;
295 }
296 }
297 }
298 Ok(())
299 }
300
301 fn assign_global(&mut self, name_range: &NameRange, value_range: &NameRange) -> Result<()> {
302 let name = self.name(name_range);
303 match name {
304 "unicode_prefix" | "unicode_suffix" => {
305 let action = self.read_action(value_range.start..value_range.end)?;
306 self.config.temp_map.insert(name, action);
307 }
308 _ => {
309 let p = globals::DEFAULTS.get(name).ok_or_else(|| {
310 error_span(
311 format!("Invalid global '{}'", name).as_str(),
312 name_range.start..name_range.end,
313 )
314 })?;
315
316 use GlobalType::*;
317 let value = GlobalProp {
318 index: p.index,
319 spec: match p.spec {
320 Timeout(_) => {
321 GlobalType::Timeout(self.config.parse_duration(value_range, 5000)?)
322 }
323 _ => unreachable!(),
324 },
325 };
326
327 self.config.global_map.insert(name, value);
328 }
329 };
330 Ok(())
331 }
332
333 fn parse_matrix(&mut self) -> Result<()> {
334 while let Some(pos) = self.skip_whitespace() {
335 if pos.1 == '[' {
336 return Ok(());
337 }
338 self.skip_whitespace();
339 let mark = self.iter.current.0;
340 match self.parse_assignment()? {
341 None => return Ok(()),
342 Some((left, right)) => {
343 self.mark_idx = mark;
344 let mut pos = self
345 .config
346 .key_position(self.name(&left))
347 .ok_or_else(|| self.error("Invalid key code"))?;
348 if (pos >> 8) as u8 >= self.config.row_count {
349 return Err(self.error(TOO_MANY_ROWS));
350 }
351
352 let mut right = Some(right);
353 while let Some(value) = &right {
354 let value = self.name(value);
355 if (pos & 0xff) as u8 >= self.config.col_count {
356 return Err(self.error(TOO_MANY_COLS));
357 }
358 self.config.assign_position_name(pos, value);
359 if let Some(code) = keycodes::key_code(value) {
360 self.config.assign_one_layer_code("main", pos, code);
361 }
362 pos += 1;
363 right = self.next_assignment_value();
364 }
365 }
366 }
367 }
368 Ok(())
369 }
370
371 fn parse_aliases(&mut self) -> Result<()> {
372 while let Some(pos) = self.skip_whitespace() {
373 if pos.1 == '[' {
374 return Ok(());
375 }
376 self.skip_whitespace();
377 match self.parse_assignment()? {
378 None => return Ok(()),
379 Some((key, right)) => {
380 let value = self.name(&right);
381 if !self.config.assign_aliases(self.name(&key), value) {
382 return Err(error_span("Unknown key name", key));
383 }
384 self.assert_no_more_values(TOO_MANY_RHS)?;
385 }
386 }
387 }
388 Ok(())
389 }
390
391 fn parse_firmware(&mut self) -> Result<()> {
392 while let Some(pos) = self.skip_whitespace() {
393 if pos.1 == '[' {
394 return Ok(());
395 }
396 self.skip_whitespace();
397 match self.parse_assignment()? {
398 None => return Ok(()),
399 Some((key, right)) => {
400 let eol = self
401 .iter
402 .find(|c| c == '\n')
403 .unwrap_or((self.config.source.len(), '\0'));
404 let key = self.name(&key);
405 let value = self.trim_value(&(right.start..eol.0));
406 value
407 .replace("#", "//")
408 .parse::<proc_macro2::TokenStream>()
409 .map_err(|_| error_span(SYNTAX_ERROR, right.start..eol.0))?;
410 self.config.firmware_map.insert(key, value);
411 }
412 }
413 }
414 Ok(())
415 }
416
417 fn parse_layer(&mut self, name: &str) -> Result<()> {
418 while let Some(pos) = self.skip_whitespace() {
419 if pos.1 == '[' {
420 return Ok(());
421 }
422 self.skip_whitespace();
423 let mark = self.iter.current.0;
424 match self.parse_assignment()? {
425 None => return Ok(()),
426 Some((left_range, right)) => {
427 self.mark_idx = mark;
428 let left = self.name(&left_range);
429
430 let alias_value = self.config.get_aliases(left);
431
432 let keypos = if let Some(list) = alias_value {
433 if list.len() == 1 {
434 list.first().copied()
435 } else {
436 None
437 }
438 } else {
439 self.config.key_position(left)
440 };
441
442 if let Some(mut keypos) = keypos {
443 if (keypos >> 8) as u8 >= self.config.row_count {
444 return Err(self.error(TOO_MANY_ROWS));
445 }
446 let mut right = Some(right);
447 while let Some(value) = &right {
448 if (keypos & 0xff) as u8 >= self.config.col_count {
449 return Err(self.error(TOO_MANY_COLS));
450 }
451
452 let code = self.read_action(value.to_owned())?;
453 self.config.assign_one_layer_code(name, keypos, code);
454
455 right = self.next_assignment_value();
456 keypos += 1;
457 }
458 } else if let Some(positions) = alias_value {
459 let positions = positions.clone();
460 let code = self.read_action(right)?;
461 for pos in positions {
462 self.config.assign_one_layer_code(name, pos, code);
463 }
464 self.assert_no_more_values(TOO_MANY_MULTI_ALIAS_RHS)?;
465 } else {
466 return Err(error_span(format!("key not found! {}", left), left_range));
467 }
468 }
469 }
470 }
471 Ok(())
472 }
473
474 fn assert_no_more_values(&mut self, msg: &str) -> Result<()> {
475 self.mark_start();
476 if self.next_assignment_value().is_some() {
477 Err(self.error(msg))
478 } else {
479 Ok(())
480 }
481 }
482
483 fn read_action(&mut self, name_range: NameRange) -> Result<u16> {
484 let name = self.name(&name_range);
485
486 if let Some(code) = keycodes::key_code(name) {
487 Ok(code)
488 } else if let Some(base_code) = if self.iter.current.1 == '(' {
489 keycodes::action_code(name)
490 } else {
491 keycodes::modifier_macro(name)
492 } {
493 match base_code {
495 key_range::LAYER_MIN..=key_range::REPLACE_LAYERS_MIN => {
496 self.iter.next();
497 self.parse_layer_code(base_code)
498 }
499 key_range::MACROS_MIN => self.parse_macro(name_range),
500 _ => unimplemented!("read_action: {}", base_code),
501 }
502 } else {
503 Err(error_span(UNKNOWN_ACTION, name_range))
504 }
505 }
506
507 fn read_arg(&mut self) -> NameRange {
508 self.read(invalid_arg_char)
509 }
510
511 fn read_timeout(&mut self) -> Result<u16> {
512 let nr = self.read_arg();
513 self.config.parse_duration(&nr, 5000)
514 }
515
516 fn read(&mut self, f: impl Fn(char) -> bool) -> NameRange {
517 if let Some(start) = self.next_non_ws() {
518 if invalid_seq_char(start.1) {
519 self.iter.put_back(start);
520 return start.0..start.0;
521 }
522 self.mark_start();
523 if let Some(end) = self.iter.find(f) {
524 self.iter.put_back(end);
525 start.0..end.0
526 } else {
527 start.0..self.iter.current.0
528 }
529 } else {
530 self.iter.current.0..self.iter.current.0
531 }
532 }
533
534 fn read_sequence(&mut self) -> NameRange {
535 if let Some(start) = self.next_non_ws() {
536 if invalid_seq_char(start.1) {
537 self.iter.put_back(start);
538 return start.0..start.0;
539 }
540 self.mark_start();
541 if let Some(end) = self.iter.find(invalid_seq_char) {
542 self.iter.put_back(end);
543 start.0..end.0
544 } else {
545 start.0..self.iter.current.0
546 }
547 } else {
548 self.iter.current.0..self.iter.current.0
549 }
550 }
551
552 fn expect(&mut self, c: char) -> Result<()> {
553 self.mark_start();
554 if let Some(start) = self.next_non_ws() {
555 if start.1 == c {
556 return Ok(());
557 }
558 }
559
560 Err(self.error(format!("Expected {} ", c)))
561 }
562
563 fn name(&self, name_range: &NameRange) -> &'source str {
564 self.config.name(name_range)
565 }
566
567 fn trim_value(&self, name_range: &NameRange) -> &'source str {
568 let mut value = &self.config.source[name_range.start..name_range.end];
569 if let Some(i) = value.rfind('#') {
570 value = &value[..i];
571 }
572
573 value.trim()
574 }
575
576 fn dualaction(&mut self, hold: u16) -> Result<u16> {
577 self.expect(',')?;
578
579 let tap_name = self.read_arg();
580
581 let tap = self.read_action(tap_name)?;
582
583 let Some(c) = self.next_non_ws() else {
584 return Err(self.error(EOF));
585 };
586
587 Ok(if c.1 == ')' {
588 self.add_macro(Macro::DualAction(tap, hold))
589 } else {
590 let t1 = self.read_timeout()?;
591 let Some(c) = self.next_non_ws() else {
592 return Err(self.error(EOF));
593 };
594 if c.1 == ')' {
595 self.add_macro(Macro::TimedDualAction(tap, hold, t1, u16::MAX))
596 } else {
597 let t2 = self.read_timeout()?;
598 self.expect(')')?;
599 self.add_macro(Macro::TimedDualAction(tap, hold, t1, t2))
600 }
601 })
602 }
603
604 fn parse_macro(&mut self, name_range: NameRange) -> Result<u16> {
605 let name = self.name(&name_range);
606 let id = match name {
607 "macro" => {
608 self.iter.next();
609 let seq = self.macro_sequence()?;
610 self.expect(')')?;
611 if seq.len() == 2
612 && matches!(self.get_macro(seq[0]), Some(Macro::Hold(..)))
613 && matches!(self.get_macro(seq[1]), Some(Macro::Release(..)))
614 {
615 self.add_macro(Macro::HoldRelease {
616 hold: seq[0],
617 release: seq[1],
618 })
619 } else {
620 self.add_macro(Macro::Tap(seq))
621 }
622 }
623 "hold" => {
624 self.iter.next();
625 let seq = self.macro_sequence()?;
626 self.expect(')')?;
627 self.add_macro(Macro::Hold(seq))
628 }
629 "release" => {
630 self.iter.next();
631 let seq = self.macro_sequence()?;
632 self.expect(')')?;
633 self.add_macro(Macro::Release(seq))
634 }
635 "overload" => {
636 self.iter.next();
637 let name = self.read_arg();
638 if name.is_empty() {
639 return Err(self.error("Missing name"));
640 }
641 let hold = self.get_layer_index(name)? + key_range::LAYER_MIN;
642
643 self.dualaction(hold)?
644 }
645 "dualaction" => {
646 self.iter.next();
647 let hold_name = self.read_arg();
648 let hold = self.read_action(hold_name)?;
649
650 self.dualaction(hold)?
651 }
652 "unicode" => {
653 self.iter.next();
654 let uc = self.read_hex_codes()?;
655 self.expect(')')?;
656 let mac = Macro::Tap(self.config.unicode_to_seq(uc));
657 self.add_macro(mac)
658 }
659 "delay" => {
660 self.iter.next();
661 let nr = self.read_arg();
662 let d = self.config.parse_duration(&nr, 5000)?;
663 self.expect(')')?;
664 let mac = Macro::Delay(d);
665 self.add_macro(mac)
666 }
667 name => {
668 let (modifiers, keycode) = name
669 .rsplit_once('-')
670 .ok_or_else(|| error_span(UNKNOWN_ACTION, name_range.clone()))?;
671 let modifiers = keycodes::modifiers_to_bit_map(modifiers).ok_or_else(|| {
672 ConfigError::new(
673 format!("Invalid modifiers '{}'", modifiers),
674 name_range.start..name_range.start + modifiers.len(),
675 )
676 })?;
677 let keycode = keycodes::key_code(keycode)
678 .ok_or_else(|| error_span(UNKNOWN_ACTION, name_range))?;
679
680 self.add_macro(Macro::Modifier { keycode, modifiers })
681 }
682 };
683 Ok(id + key_range::MACROS_MIN)
684 }
685
686 fn read_hex_codes(&mut self) -> Result<char> {
687 let mut result: u32 = 0;
688 let start = self.iter.current.0;
689 while let Some(ic) = self.iter.next() {
690 match ic.1 {
691 'a'..='f' => {
692 result = (result << 4) + 10 + (ic.1 as u32) - ('a' as u32);
693 }
694 'A'..='F' => {
695 result = (result << 4) + 10 + (ic.1 as u32) - ('A' as u32);
696 }
697 '0'..='9' => {
698 result = (result << 4) + (ic.1 as u32) - ('0' as u32);
699 }
700 ' ' => {}
701 ')' => {
702 self.iter.put_back(ic);
703 break;
704 }
705 _ => {
706 return Err(error_span(
707 "Invalid unicode digit",
708 self.iter.current.0..self.iter.current.0 + 1,
709 ))
710 }
711 }
712 }
713 char::from_u32(result)
714 .ok_or_else(|| error_span("Invalid unicode", start..self.iter.current.0 + 1))
715 }
716
717 fn macro_sequence(&mut self) -> Result<Vec<u16>> {
718 let mut seq = Vec::new();
719 loop {
720 let range = self.read_sequence();
721 if range.is_empty() {
722 break;
723 }
724 let name = self.name(&range);
725 if let Some(code) = if name.len() > 1 {
726 keycodes::key_code(name)
727 } else {
728 None
729 } {
730 seq.push(code);
731 } else if keycodes::action_code(name).is_some() && self.iter.current.1 == '(' {
732 seq.push(self.read_action(range)?);
733 } else {
734 let (modifiers, keycode) = name.rsplit_once('-').unwrap_or(("", name));
735 let mod_mac = if !modifiers.is_empty()
736 && keycodes::modifiers_to_bit_map(modifiers).is_some()
737 {
738 keycodes::key_code(keycode).is_some()
739 } else {
740 false
741 };
742 if mod_mac {
743 seq.push(self.parse_macro(range)?);
744 } else {
745 for c in name.chars() {
746 let u = unshifted_char_code(c);
747 if u != c {
748 seq.push(
749 key_range::MACROS_MIN
750 + self.add_macro(Macro::Modifier {
751 keycode: keycodes::char_to_code(u),
752 modifiers: keycodes::SHIFT_MOD,
753 }),
754 );
755 } else {
756 let code = keycodes::char_to_code(c);
757 if code != 0 {
758 seq.push(code)
759 } else {
760 let mac = Macro::Tap(self.config.unicode_to_seq(c));
761 seq.push(key_range::MACROS_MIN + self.add_macro(mac));
762 }
763 }
764 }
765 }
766 }
767 }
768 Ok(seq)
769 }
770
771 fn get_macro(&self, code: u16) -> Option<&Macro> {
772 if matches!(code, key_range::MACROS_MIN..=key_range::MACROS_MAX) {
773 self.config
774 .macros
775 .get((code - key_range::MACROS_MIN) as usize)
776 } else {
777 None
778 }
779 }
780
781 fn add_macro(&mut self, mac: Macro) -> u16 {
782 let bin = mac.serialize();
783 if let Some(id) = self.config.macros_names.get(&bin) {
784 return *id;
785 }
786 let id = self.config.macros.len() as u16;
787
788 self.config.macros.push(mac);
789 self.config.macros_names.insert(bin, id);
790 id
791 }
792
793 fn get_layer_index(&mut self, name_range: NameRange) -> Result<u16> {
794 let name = &self.config.source[name_range.start..name_range.end];
795 if let Some(index) = self.config.get_layer_index(name) {
796 Ok(index)
797 } else {
798 Err(error_span(
799 format!("Unknown layer name {}", name),
800 name_range,
801 ))
802 }
803 }
804
805 fn parse_layer_code(&mut self, base_code: u16) -> Result<u16> {
806 self.mark_start();
807 if let Some(start) = self.next_non_ws() {
808 self.mark_idx = start.0;
809 if let Some(end) = self.iter.find(|c| c == ')' || c.is_whitespace()) {
810 let end_mark = self.iter.current.0 - 1;
811 if end.1 == ')'
812 || self
813 .next_non_ws()
814 .and_then(|c| if c.1 == '(' { Some(c) } else { None })
815 .is_some()
816 {
817 return Ok(base_code + self.get_layer_index(start.0..end.0)?);
818 }
819 self.iter.current.0 = end_mark;
820 }
821 }
822 Err(self.error("Invalid layer(...) action"))
823 }
824
825 fn parse_assignment(&mut self) -> Result<Option<(NameRange, NameRange)>> {
826 if let Some(left) = self.read_word()? {
827 if self.match_char('=') {
828 if let Some(right) = self.next_assignment_value() {
829 return Ok(Some((left, right)));
830 } else {
831 return Err(self.error("Missing RHS"));
832 }
833 } else {
834 return Err(self.error("Missing ="));
835 }
836 }
837 Ok(None)
838 }
839
840 fn next_assignment_value(&mut self) -> Option<NameRange> {
841 let start = self.iter.find(|c| c == '\n' || !c.is_whitespace())?;
842 self.mark_start();
843 if start.1 == '\n' {
844 return None;
845 }
846 if let Some(parens) = match_paren(start.1) {
847 match self.iter.find_close_paren(parens) {
848 Some(end) => Some(start.0..end.0),
849 None => Some(start.0..self.iter.current.0),
850 }
851 } else {
852 match self.iter.find(invalid_seq_char) {
853 Some(end) => {
854 self.iter.put_back(end);
855 Some(start.0..end.0)
856 }
857 None => Some(start.0..self.iter.current.0),
858 }
859 }
860 }
861
862 fn mark_start(&mut self) {
863 self.mark_idx = self.iter.current.0;
864 }
865
866 fn error(&self, message: impl Into<String>) -> ConfigError {
867 ConfigError::new(message.into(), self.mark_idx..self.iter.current.0)
868 }
869
870 fn read_word(&mut self) -> Result<Option<NameRange>> {
871 match self.iter.find(|c| c == '\n' || !c.is_whitespace()) {
872 None => Ok(None),
873 Some(start) => {
874 self.mark_start();
875 if start.1 == '\n' {
876 return Ok(None);
877 }
878 match self.iter.find(|c| c.is_whitespace()) {
879 Some(end) => {
880 if end.1 == '\n' {
881 self.iter.put_back(end);
882 }
883 Ok(Some(start.0..end.0))
884 }
885 None => Err(self.error("Expected word")),
886 }
887 }
888 }
889 }
890
891 fn match_char(&mut self, c: char) -> bool {
892 match self.next_non_ws() {
893 None => false,
894 Some(start) => start.1 == c,
895 }
896 }
897
898 fn build_config(self) -> KeyboardConfig<'source> {
899 self.config
900 }
901
902 fn skip_whitespace(&mut self) -> Option<IndexChar> {
903 self.next_non_ws().inspect(|&item| {
904 self.iter.put_back(item);
905 })
906 }
907
908 #[inline]
909 fn next_non_ws(&mut self) -> Option<IndexChar> {
910 self.iter.find(non_ws_char)
911 }
912
913 fn assert_no_suffix(&self, tag_end: usize, end: usize) -> Result<()> {
914 if tag_end == end {
915 Ok(())
916 } else {
917 Err(ConfigError::new(
918 "suffix not allowed here".into(),
919 tag_end..end,
920 ))
921 }
922 }
923}
924
925fn match_paren(start: char) -> Option<(char, char)> {
926 Some(match start {
927 '(' => ('(', ')'),
928 '[' => ('[', ']'),
929 '{' => ('{', '}'),
930 _ => return None,
931 })
932}
933
934const DEFAULT_LAYERS: [(&str, u8); 6] = [
935 ("control", 1),
936 ("shift", 2),
937 ("alt", 4),
938 ("gui", 8),
939 ("altgr", 0x40),
940 ("main", 0),
941];
942
943fn data_to_usize(x: u16) -> usize {
944 u16::from_le(x) as usize
945}
946
947impl<'source> KeyboardConfig<'source> {
948 fn new(source: &'source str) -> Self {
949 let mut layers: HashMap<String, ConfigLayer> = Default::default();
950 for (i, (name, code)) in DEFAULT_LAYERS.into_iter().enumerate() {
951 layers.insert(name.into(), ConfigLayer::new(i as u16, code));
952 }
953
954 Self {
955 source,
956 global_map: Default::default(),
957 temp_map: Default::default(),
958 firmware_map: Default::default(),
959 matrix_map: Default::default(),
960 layers,
961 macros_names: Default::default(),
962 macros: Default::default(),
963 next_layer: DEFAULT_LAYERS.len() as u16,
964 row_count: 0,
965 col_count: 0,
966 }
967 }
968
969 pub fn deserialize(data: &[u16]) -> Self {
970 assert!(data.len() > 14);
971 assert_eq!(data[0], PROTOCOL_VERSION);
972
973 let mut config = Self::new("");
974
975 config.row_count = (u16::from_le(data[1]) >> 8) as u8;
976 config.col_count = (u16::from_le(data[1]) & 0xff) as u8;
977 let layer_count = (u16::from_le(data[2]) & 0xff) as usize;
978 let globals_count = u16::from_le(data[4]) as usize;
980
981 config.deserialize_globals(&mut data[5..5 + globals_count].iter().copied());
982
983 let data = &data[5 + globals_count..]; for (i, (name, _)) in DEFAULT_LAYERS.into_iter().enumerate() {
986 let layer = config.layers.get_mut(name).unwrap();
987 layer.set_binary(
988 &data[data_to_usize(data[i])..data_to_usize(data[1 + i])],
989 config.row_count as usize,
990 config.col_count as usize,
991 );
992 }
993
994 for i in DEFAULT_LAYERS.len()..layer_count {
995 let name = format!("layer{}", i);
996 config.new_layer(name.as_str(), 0);
997 let layer = config.layers.get_mut(name.as_str()).unwrap();
998 layer.set_binary(
999 &data[data_to_usize(data[i])..data_to_usize(data[1 + i])],
1000 config.row_count as usize,
1001 config.col_count as usize,
1002 );
1003 }
1004
1005 config
1008 }
1009
1010 pub fn serialize(&self) -> Vec<u16> {
1011 let layer_count = self.layers.len();
1012 let macros_count = self.macros.len();
1013
1014 let globals = self.serialize_globals();
1015
1016 let layer_base = 5 + globals.len();
1017 let mut out = vec![0; 1 + layer_count + macros_count + layer_base];
1018
1019 out[0] = PROTOCOL_VERSION.to_le();
1020 out[1] = ((self.col_count as u16) | ((self.row_count as u16) << 8)).to_le();
1021 out[2] = (layer_count as u16).to_le();
1022 out[3] = (macros_count as u16).to_le();
1023 out[4] = (globals.len() as u16).to_le();
1024
1025 out[5..layer_base].copy_from_slice(globals.as_slice());
1026
1027 let mut layers = self.layers.values().collect::<Vec<_>>();
1028 layers.sort_by(|a, b| Ord::cmp(&a.index, &b.index));
1029 for (i, mut l) in layers
1030 .iter()
1031 .map(|l| l.serialize(self.row_count as usize, self.col_count as usize))
1032 .enumerate()
1033 {
1034 out[layer_base + i] = ((out.len() - layer_base) as u16).to_le();
1035 out.append(&mut l);
1036 }
1037 let macro_base = layer_base + layer_count;
1038
1039 for (i, mut m) in self.macros.iter().map(|m| m.serialize()).enumerate() {
1040 out[macro_base + i] = ((out.len() - layer_base) as u16).to_le();
1041 out.append(&mut m);
1042 }
1043
1044 out[macro_base + macros_count] = ((out.len() - layer_base) as u16).to_le();
1045
1046 out
1047 }
1048
1049 pub fn deserialize_globals(&mut self, data: &mut impl Iterator<Item = u16>) {
1050 while let Some(gp) = GlobalProp::deserialize(data) {
1051 if let Some(name) = gp.default_name() {
1052 self.global_map.insert(name, gp);
1053 }
1054 }
1055 }
1056
1057 pub fn serialize_globals(&self) -> Vec<u16> {
1058 let mut out = self.global_map.values().collect::<Vec<_>>();
1059 out.sort_by(|a, b| Ord::cmp(&a.index, &b.index));
1060 out.into_iter().flat_map(|v| v.serialize()).collect()
1061 }
1062
1063 fn name(&self, name_range: &NameRange) -> &'source str {
1064 let start = if name_range.len() > 1 && self.source[name_range.start..].starts_with('\\') {
1065 name_range.start + 1
1066 } else {
1067 name_range.start
1068 };
1069 &self.source[start..name_range.end]
1070 }
1071
1072 fn unicode_to_seq(&mut self, uc: char) -> Vec<u16> {
1073 let uc = uc as u32;
1074
1075 let mut seq = vec![*self.temp_map.get("unicode_prefix").unwrap_or(&0)];
1076
1077 for i in 0..7 {
1078 let i = (6 - i) << 2;
1079 let d = ((uc >> i) & 0xf) as u16;
1080
1081 let kc = match d {
1082 0 if seq.len() == 1 => continue,
1083 0 => BASIC_0,
1084 10..=15 => BASIC_A + d - 10,
1085 _ => BASIC_1 + d - 1,
1086 };
1087 seq.push(kc);
1088 }
1089
1090 seq.push(*self.temp_map.get("unicode_suffix").unwrap_or(&0));
1091
1092 seq
1093 }
1094
1095 fn parse_duration(&mut self, value_range: &NameRange, max: u16) -> Result<u16> {
1096 if let Ok(n) = self.name(value_range).parse::<u16>() {
1097 if n <= max {
1098 return Ok(n);
1099 }
1100 }
1101 Err(error_span(
1102 format!("Invalid duration; only 0 to {} milliseconds are valid", max),
1103 value_range.start..value_range.end,
1104 ))
1105 }
1106
1107 pub fn key_position(&self, name: &str) -> Option<u16> {
1108 if let Some(name) = name.strip_prefix("0x") {
1109 if let Ok(pos) = u16::from_str_radix(name, 16) {
1110 return Some(match name.len() {
1111 2 => (pos & 0xf0) << 4 | (pos & 0xf),
1112 3..=4 => pos,
1113 _ => return None,
1114 });
1115 }
1116 }
1117 None
1118 }
1119
1120 pub fn global(&self, name: &str) -> Option<GlobalProp> {
1121 self.global_map.get(name).copied()
1122 }
1123
1124 fn take_global(&mut self, name: &'source str) -> Result<GlobalProp> {
1125 match self.global_map.remove(name) {
1126 Some(g) => Ok(g),
1127 None => GlobalProp::new_default(name).map_err(|e| ConfigError::from(e.as_str())),
1128 }
1129 }
1130
1131 fn insert_global(&mut self, name: &'source str, value: GlobalProp) {
1132 self.global_map.insert(name, value);
1133 }
1134
1135 fn assign_aliases(&mut self, key: &str, value: &str) -> bool {
1136 if let Some(pos) = self.key_position(key) {
1137 self.assign_position_name(pos, value);
1138 return true;
1139 }
1140 if let Some(positions) = self.get_aliases(key) {
1141 let positions = positions.clone();
1142 for pos in positions {
1143 self.assign_position_name(pos, value);
1144 }
1145 return true;
1146 }
1147 false
1148 }
1149
1150 fn assign_position_name(&mut self, pos: u16, name: &str) {
1151 if let Some(code) = key_code(name) {
1152 let name = format!("{code:04X}");
1153 if let Some(v) = self.matrix_map.get_mut(name.as_str()) {
1154 v.push(pos);
1155 } else {
1156 self.matrix_map.insert(name, vec![pos]);
1157 }
1158 } else if let Some(v) = self.matrix_map.get_mut(name) {
1159 v.push(pos);
1160 } else {
1161 self.matrix_map.insert(name.into(), vec![pos]);
1162 }
1163 }
1164
1165 pub fn get_aliases(&self, name: &str) -> Option<&Vec<u16>> {
1166 if let Some(code) = key_code(name) {
1167 self.matrix_map.get(format!("{code:04X}").as_str())
1168 } else {
1169 self.matrix_map.get(name)
1170 }
1171 }
1172
1173 pub fn code_at(&self, name: &str, rowcol: u16) -> u16 {
1174 if let Some(layer) = self.layers.get(name) {
1175 return layer.code_at(rowcol);
1176 }
1177 0
1178 }
1179
1180 fn assign_one_layer_code(&mut self, name: &str, pos: u16, code: u16) {
1181 self.layers.get_mut(name).unwrap().set_code(pos, code);
1182 }
1183
1184 fn new_layer(&mut self, name: &str, code: u8) {
1185 self.layers
1186 .insert(name.into(), ConfigLayer::new(self.next_layer, code));
1187
1188 self.next_layer += 1;
1189 }
1190
1191 fn get_layer_index(&self, name: &str) -> Option<u16> {
1192 self.layers.get(name).map(|l| l.index)
1193 }
1194
1195 fn scan_layer_names(&mut self) -> Result<()> {
1196 #[derive(PartialEq)]
1197 enum State {
1198 Ready,
1199 Read(usize, usize),
1200 Search,
1201 }
1202 let mut in_comment = false;
1203 let mut escaped = false;
1204 let mut paren = 0;
1205 let mut parens = ('(', ')');
1206 let mut state = State::Ready;
1207 for (i, c) in self.source.char_indices() {
1208 match c {
1209 _ if escaped => {
1210 escaped = false;
1211 }
1212 '\n' if paren == 0 => {
1213 state = State::Ready;
1214 in_comment = false;
1215 }
1216 _ if in_comment => {}
1217 '#' => {
1218 in_comment = true;
1219 }
1220 '\\' => {
1221 escaped = true;
1222 }
1223 _ if paren > 0 => {
1224 if c == parens.0 {
1225 paren += 1;
1226 } else if c == parens.1 {
1227 paren -= 1;
1228 }
1229 }
1230 _ => match state {
1231 State::Read(s, e) => match c {
1232 ':' if s == e => {
1233 state = State::Read(s, i);
1234 }
1235 ']' => {
1236 self.ensure_section(s, e, i)?;
1237 state = State::Search;
1238 }
1239 _ => {}
1240 },
1241 State::Ready => match c {
1242 '[' => {
1243 state = State::Read(i + 1, i + 1);
1244 }
1245 _ if c.is_whitespace() => {}
1246 _ => {
1247 state = State::Search;
1248 if let Some(p) = match_paren(c) {
1249 parens = p;
1250 paren = 1;
1251 }
1252 }
1253 },
1254 State::Search => {}
1255 },
1256 }
1257 }
1258 Ok(())
1259 }
1260
1261 fn ensure_section(&mut self, s: usize, e: usize, i: usize) -> Result<()> {
1262 let (name, suffix) = if s == e {
1263 (&self.source[s..i], &self.source[s..e])
1264 } else {
1265 (&self.source[s..e], &self.source[e + 1..i])
1266 };
1267
1268 match name {
1269 "matrix" => {
1270 let mut iter = suffix.split_terminator('x');
1271 if let (Some(row_count), Some(col_count)) = (iter.next(), iter.next()) {
1272 if let (Ok(row_count), Ok(col_count)) =
1273 (row_count.parse::<u8>(), col_count.parse::<u8>())
1274 {
1275 self.row_count = row_count;
1276 self.col_count = col_count;
1277 return Ok(());
1278 }
1279 }
1280
1281 return Err(ConfigError::new(
1282 "expected [matrix:rxc] where r and c are row column size".into(),
1283 s..i,
1284 ));
1285 }
1286 "aliases" => {}
1287 _ => {
1288 let code = keycodes::modifiers_to_bit_map(suffix).ok_or_else(|| {
1289 ConfigError::new(format!("Invalid layer suffix '{}'", suffix), e + 1..i)
1290 })?;
1291
1292 if let Some(layer) = self.layers.get(name) {
1293 if layer.suffix != code && code != 0 {
1294 return Err(ConfigError::new(
1295 format!(
1296 "layer suffix may not be changed; {} != {}",
1297 keycodes::modifiers_to_string(layer.suffix),
1298 suffix,
1299 ),
1300 s..i,
1301 ));
1302 }
1303 } else {
1304 self.new_layer(name, code);
1305 }
1306 }
1307 }
1308
1309 Ok(())
1310 }
1311
1312 pub fn firmware_get(&self, arg: &str) -> Option<&str> {
1313 self.firmware_map
1314 .get(arg)
1315 .or_else(|| {
1316 let arg = arg.to_uppercase();
1317 self.firmware_map.get(arg.as_str())
1318 })
1319 .copied()
1320 }
1321}
1322
1323impl ConfigLayer {
1324 fn new(index: u16, suffix: u8) -> Self {
1325 Self {
1326 codes: Default::default(),
1327 index,
1328 suffix,
1329 }
1330 }
1331
1332 fn set_binary(&mut self, data: &[u16], row_count: usize, col_count: usize) {
1333 self.suffix = u16::from_le(data[0]) as u8;
1334
1335 let data = &data[1..];
1336 if row_count * col_count == data.len() {
1337 for row in 0..row_count {
1338 for col in 0..col_count {
1339 self.codes.insert(
1340 ((row << 8) + col) as u16,
1341 u16::from_le(data[row * col_count + col]),
1342 );
1343 }
1344 }
1345 } else {
1346 let mut k = 0;
1347 for (i, v) in data.iter().enumerate() {
1348 let v = u16::from_le(*v);
1349 if i & 1 == 0 {
1350 k = v;
1351 } else {
1352 self.codes.insert(k, v);
1353 }
1354 }
1355 }
1356 }
1357
1358 fn serialize(&self, row_count: usize, col_count: usize) -> Vec<u16> {
1359 let mut bin = vec![0];
1360 bin[0] = (self.suffix as u16).to_le();
1361 if self.codes.len() * 3 > row_count * col_count {
1362 bin.resize(1 + row_count * col_count, 0);
1364 for (k, v) in self.codes.iter() {
1365 let i = (k >> 8) as usize * col_count + (k & 0xff) as usize;
1366 let _ = (k, v, i, k >> 8, (k & 0xff));
1367 bin[i + 1] = v.to_le();
1368 }
1369 } else {
1370 bin.resize(1 + self.codes.len() * 2, 0);
1371 let mut codes = self.codes.iter().collect::<Vec<_>>();
1372 codes.sort_by_key(|k| k.0);
1373 for (i, (k, v)) in codes.into_iter().enumerate() {
1374 bin[i * 2 + 1] = k.to_le();
1375 bin[i * 2 + 2] = v.to_le();
1376 }
1377 }
1379 bin
1380 }
1381
1382 pub fn code_at(&self, pos: u16) -> u16 {
1383 *self.codes.get(&pos).unwrap_or(&0)
1384 }
1385
1386 fn set_code(&mut self, pos: u16, code: u16) {
1387 self.codes.insert(pos, code);
1388 }
1389}
1390
1391fn error_span(message: impl Into<String>, range: NameRange) -> ConfigError {
1392 ConfigError::new(message.into(), range)
1393}
1394
1395pub fn compile(source: &str) -> Result<KeyboardConfig> {
1396 let mut parser = Parser::new(source);
1397
1398 parser.parse_sections()?;
1399 Ok(parser.build_config())
1400}
1401
1402#[cfg(test)]
1403#[path = "compiler_test.rs"]
1404mod test;