1use layouts_rs::{Layout, Layouts};
2use std::collections::HashMap;
3use std::fmt;
4use std::ops::Range;
5use std::str::FromStr;
6
7pub type Index = Range<usize>;
8pub type Indices = Vec<Index>;
9pub type Map<'a> = HashMap<&'a str, &'a str>;
10
11#[derive(Debug, Clone)]
12pub enum Error {
13 UnknownMatch { s: String },
14}
15
16pub fn format_indices(ranges: &[Index]) -> String {
17 ranges
18 .iter()
19 .map(|range| format!("{}-{}", range.start, range.end))
20 .collect::<Vec<_>>()
21 .join(", ")
22}
23
24pub fn maybe_quote(text: &str) -> String {
25 if text.contains(' ') {
26 format!("\"{}\"", text)
27 } else {
28 text.to_string()
29 }
30}
31
32#[derive(Debug, Clone)]
33pub struct Mapping<'a>(pub TriggerList<'a>, pub TriggerMode, pub ResultList<'a>);
34
35impl<'a> Mapping<'a> {
36 pub fn implied_state(&self) -> Option<Vec<Self>> {
37 if let Some(triggerlists) = self.0.implied_state() {
39 if let Some(resultlists) = self.2.implied_state() {
40 if triggerlists.len() == 2 && resultlists.len() == 2 {
42 Some(vec![
43 Self(
44 triggerlists[0].clone(),
45 self.1.clone(),
46 resultlists[0].clone(),
47 ),
48 Self(
49 triggerlists[1].clone(),
50 self.1.clone(),
51 resultlists[1].clone(),
52 ),
53 ])
54 } else {
55 None
56 }
57 } else {
58 None
59 }
60 } else {
61 None
62 }
63 }
64}
65
66impl<'a> fmt::Display for Mapping<'a> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(f, "{} {} {}", self.0, self.1, self.2)
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
74pub struct TriggerConditionList(pub Vec<Vec<kll_core::TriggerCondition>>);
75
76#[derive(Debug, Clone)]
77pub struct TriggerList<'a>(pub Vec<Vec<Trigger<'a>>>);
78
79impl<'a> TriggerList<'a> {
80 pub fn iter(&self) -> impl Iterator<Item = &Trigger> + '_ {
81 self.0.iter().flatten()
82 }
83
84 pub fn kll_core_guide(&self) -> Vec<u8> {
89 let mut buf = Vec::new();
90 for combo in &self.0 {
91 buf.push(combo.len() as u8);
93 for elem in combo {
95 unsafe {
96 buf.extend_from_slice(elem.kll_core_condition().bytes());
97 }
98 }
99 }
100 buf.push(0);
102 buf
103 }
104
105 pub fn kll_core_condition_guide(&self) -> TriggerConditionList {
108 let mut sequence_buf = Vec::new();
109 for combo in &self.0 {
110 let mut combo_buf = Vec::new();
111 for elem in combo {
113 combo_buf.push(elem.kll_core_condition());
114 }
115 sequence_buf.push(combo_buf);
116 }
117 TriggerConditionList(sequence_buf)
118 }
119
120 fn implied_state(&self) -> Option<Vec<Self>> {
121 assert!(
126 self.0.len() == 1,
127 "TriggerList must only have 1 sequence element. (may not be implemented yet)"
128 );
129 assert!(
130 self.0[0].len() == 1,
131 "TriggerList must only have 1 combo element. (feature may not be implemented yet)"
132 );
133 self.0[0][0].implied_state().map(|triggers| {
134 vec![
135 Self(vec![vec![triggers[0].clone()]]),
136 Self(vec![vec![triggers[1].clone()]]),
137 ]
138 })
139 }
140}
141
142impl<'a> fmt::Display for TriggerList<'a> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 write!(
145 f,
146 "{}",
147 self.0
148 .iter()
149 .map(|combo| combo
150 .iter()
151 .map(|t| format!("{}", t))
152 .collect::<Vec<_>>()
153 .join(" + "))
154 .collect::<Vec<_>>()
155 .join(", ")
156 )
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Hash)]
162pub struct ResultCapabilitiesList(pub Vec<Vec<kll_core::Capability>>);
163
164#[derive(Debug, Clone)]
165pub struct ResultList<'a>(pub Vec<Vec<Action<'a>>>);
166
167impl<'a> ResultList<'a> {
168 pub fn iter(&self) -> impl Iterator<Item = &Action> + '_ {
169 self.0.iter().flatten()
170 }
171
172 pub fn kll_core_guide(&self, layouts: &mut Layouts) -> Vec<u8> {
177 let mut buf = Vec::new();
178 for combo in &self.0 {
179 buf.push(combo.len() as u8);
181 for elem in combo {
183 unsafe {
184 buf.extend_from_slice(elem.kll_core_condition(layouts).bytes());
185 }
186 }
187 }
188 buf.push(0);
190 buf
191 }
192
193 pub fn kll_core_capability_guide(&self, layouts: &mut Layouts) -> ResultCapabilitiesList {
196 let mut sequence_buf = Vec::new();
197 for combo in &self.0 {
198 let mut combo_buf = Vec::new();
199 for elem in combo {
201 combo_buf.push(elem.kll_core_condition(layouts));
202 }
203 sequence_buf.push(combo_buf);
204 }
205 ResultCapabilitiesList(sequence_buf)
206 }
207
208 fn implied_state(&self) -> Option<Vec<Self>> {
209 assert!(
214 self.0.len() == 1,
215 "ResultList must only have 1 sequence element. (may not be implemented yet)"
216 );
217 assert!(
218 self.0[0].len() == 1,
219 "ResultList must only have 1 combo element. (feature may not be implemented yet)"
220 );
221 let results = self.0[0][0].implied_state().unwrap();
222 Some(vec![
223 Self(vec![vec![results[0].clone()]]),
224 Self(vec![vec![results[1].clone()]]),
225 ])
226 }
227}
228
229impl<'a> fmt::Display for ResultList<'a> {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(
232 f,
233 "{}",
234 self.0
235 .iter()
236 .map(|combo| combo
237 .iter()
238 .map(|t| format!("{}", t))
239 .collect::<Vec<_>>()
240 .join(" + "))
241 .collect::<Vec<_>>()
242 .join(", ")
243 )
244 }
245}
246
247#[derive(Debug, Clone)]
248pub enum Statement<'a> {
249 Define((&'a str, &'a str)),
250 Variable((&'a str, Option<usize>, &'a str)),
251 Capability((&'a str, Capability<'a>)),
252 Keymap(Mapping<'a>),
253 Position((Indices, Position)),
254 Pixelmap((Indices, PixelDef)),
255 Animation((&'a str, Animation<'a>)),
256 Frame((&'a str, Indices, Vec<Pixel<'a>>)),
257 NOP,
258}
259
260impl<'a> fmt::Display for Statement<'a> {
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 match self {
263 Self::Define((name, val)) => write!(f, "{} = {};", name, maybe_quote(val)),
264 Self::Variable((name, index, val)) => {
265 if let Some(index) = index {
266 write!(
267 f,
268 "{}[{}] = {};",
269 maybe_quote(name),
270 index,
271 maybe_quote(val)
272 )
273 } else {
274 write!(f, "{} = {};", maybe_quote(name), maybe_quote(val))
275 }
276 }
277 Self::Capability((name, cap)) => write!(f, "{} = {};", name, cap),
278 Self::Keymap(mapping) => write!(f, "{};", mapping),
279 Self::Position((indices, pos)) => {
280 write!(f, "P[{}] <= {};", format_indices(indices), pos)
281 }
282 Self::Pixelmap((indices, map)) => write!(
283 f,
284 "P[{}]{} : {};",
285 format_indices(indices),
286 map.channels
287 .iter()
288 .map(|(c, w)| format!("{}:{}", c, w))
289 .collect::<Vec<String>>()
290 .join(", "),
291 map.scancode
292 .map(|x| format!("S{}", x))
293 .unwrap_or_else(|| "None".to_string())
294 ),
295 Self::Animation((name, anim)) => write!(f, "A[{}] <= {:?};", name, anim.modifiers),
296 Self::Frame((name, indices, frame)) => write!(
297 f,
298 "A[{}, {}] <= {:?};",
299 name,
300 format_indices(indices),
301 frame
302 ),
303 Self::NOP => Ok(()),
304 }
305 }
306}
307
308#[derive(Debug, Default, Clone, Merge)]
309pub struct Position {
310 pub x: f32, pub y: f32, pub z: f32, pub rx: f32, pub ry: f32, pub rz: f32, }
317
318impl Position {
319 pub fn from_map(map: Map) -> Self {
320 let mut pos = Position::default();
321 for (k, v) in map.iter() {
322 let v = v.parse::<f32>().unwrap();
323 match *k {
324 "x" => pos.x = v,
325 "y" => pos.y = v,
326 "z" => pos.z = v,
327 "rx" => pos.rx = v,
328 "ry" => pos.ry = v,
329 "rz" => pos.rz = v,
330 _ => {}
331 }
332 }
333
334 pos
335 }
336}
337
338impl fmt::Display for Position {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 if self.x != 0. {
341 write!(f, "x:{}", self.x)?;
342 }
343 if self.y != 0. {
344 write!(f, "y:{}", self.y)?;
345 }
346 if self.z != 0. {
347 write!(f, "z:{}", self.z)?;
348 }
349 if self.rx != 0. {
350 write!(f, "x:{}", self.rx)?;
351 }
352 if self.ry != 0. {
353 write!(f, "y:{}", self.ry)?;
354 }
355 if self.rz != 0. {
356 write!(f, "z:{}", self.rz)?;
357 }
358 Ok(())
359 }
360}
361
362#[derive(Debug, Default, Clone, Merge)]
363pub struct PixelDef {
364 #[combine]
365 pub channels: Vec<(usize, usize)>,
366 pub scancode: Option<usize>,
367}
368
369impl PixelDef {
370 pub fn new(channelmap: Map, scancode: Option<usize>) -> Self {
371 let channels = channelmap
372 .iter()
373 .map(|(k, v)| {
374 let k = k.parse::<usize>().unwrap();
375 let v = v.parse::<usize>().unwrap();
376 (k, v)
377 })
378 .collect::<Vec<_>>();
379
380 PixelDef { scancode, channels }
381 }
382}
383
384#[derive(Debug, Default, Clone)]
385pub struct Animation<'a> {
386 pub modifiers: Map<'a>,
387 pub frames: Vec<Vec<Pixel<'a>>>,
388}
389
390#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
391pub struct Capability<'a> {
392 pub function: &'a str,
393 pub args: Vec<&'a str>,
395}
396
397impl<'a> Capability<'a> {
398 pub fn new(function: &'a str, args: Vec<&'a str>) -> Self {
399 Capability { function, args }
400 }
401}
402
403impl<'a> fmt::Display for Capability<'a> {
404 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
405 write!(
406 f,
407 "{}({:?})",
408 self.function,
409 self.args
410 .iter()
411 .map(|arg| arg.to_string())
412 .collect::<Vec<_>>()
413 .join(", ")
414 )
415 }
416}
417
418#[derive(Debug, PartialEq, Eq, Hash, Clone)]
419pub enum LayerMode {
420 Normal,
421 Shift,
422 Latch,
423 Lock,
424}
425
426impl FromStr for LayerMode {
427 type Err = Error;
428
429 fn from_str(s: &str) -> Result<Self, Self::Err> {
430 Ok(match s {
431 "Layer" => Self::Normal,
432 "LayerShift" => Self::Shift,
433 "LayerLatch" => Self::Latch,
434 "LayerLock" => Self::Lock,
435 _ => {
436 return Err(Error::UnknownMatch { s: s.to_string() });
437 }
438 })
439 }
440}
441
442impl fmt::Display for LayerMode {
443 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
444 match self {
445 Self::Normal => write!(f, "Layer"),
446 Self::Shift => write!(f, "LayerShift"),
447 Self::Latch => write!(f, "LayerLatch"),
448 Self::Lock => write!(f, "LayerLock"),
449 }
450 }
451}
452
453#[derive(Debug, PartialEq, Eq, Hash, Clone)]
454pub enum TriggerType<'a> {
455 Key(Key<'a>),
456 Layer((LayerMode, Indices)),
457 Indicator(Indices),
458 Generic((usize, usize, Option<usize>)),
459 Animation(&'a str),
460}
461
462impl<'a> fmt::Display for TriggerType<'a> {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 match self {
465 Self::Key(trigger) => write!(f, "{}", trigger),
466 Self::Layer((mode, layer)) => write!(f, "{}[{}]", mode, format_indices(layer)),
467 Self::Indicator(indicators) => {
468 if indicators.len() > 1 {
469 write!(f, "I[{}]", format_indices(indicators))
470 } else {
471 write!(f, "I{}", format_indices(indicators))
472 }
473 }
474 Self::Generic((bank, index, param)) => {
475 if let Some(param) = ¶m {
476 write!(f, "T[{}, {}]({})", bank, index, param)
477 } else {
478 write!(f, "T[{}, {}]", bank, index)
479 }
480 }
481 Self::Animation(name) => write!(f, "A[{}]", name),
482 }
483 }
484}
485
486#[derive(Debug, PartialEq, Eq, Hash, Clone)]
487pub struct Trigger<'a> {
488 pub trigger: TriggerType<'a>,
489 pub state: Option<StateMap>,
490}
491
492impl<'a> Trigger<'a> {
493 pub fn kll_core_condition(&self) -> kll_core::TriggerCondition {
505 assert!(self.state.is_some(), "state *must* be defined, use generate_state_scheduling() to convert implied state into implicit state.");
509 assert!(self.state.as_ref().unwrap().states.len() == 1, "StateMap *must* only have a single state defined, need to expand into a sequence first.");
510
511 match &self.trigger {
512 TriggerType::Key(key) => {
513 match key {
514 Key::Scancode(index) => {
515 kll_core::TriggerCondition::Switch {
516 state: self.state.as_ref().unwrap().states[0].kind.phro(),
517 index: *index as u16,
518 loop_condition_index: 0, }
520 }
521 _ => kll_core::TriggerCondition::None,
525 }
526 }
527 TriggerType::Layer((_mode, _indices)) => {
528 panic!("Missing Layer");
529 }
537 TriggerType::Indicator(_indices) => {
538 panic!("Missing indicator");
539 }
547 TriggerType::Generic((_bank, _index, _param)) => {
548 panic!("Missing Generic");
549 }
552 TriggerType::Animation(_name) => {
553 panic!("Missing Animation");
554 }
562 }
563 }
564
565 fn implied_state(&self) -> Option<Vec<Self>> {
570 if self.state.is_none() {
572 Some(vec![
573 Self {
574 trigger: self.trigger.clone(),
575 state: Some(StateMap::new(vec![State {
576 kind: StateType::Press,
577 time: None,
578 }])),
579 },
580 Self {
581 trigger: self.trigger.clone(),
582 state: Some(StateMap::new(vec![State {
583 kind: StateType::Release,
584 time: None,
585 }])),
586 },
587 ])
588 } else {
589 None
590 }
591 }
592}
593
594impl<'a> fmt::Display for Trigger<'a> {
595 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
596 if let Some(state) = &self.state {
597 write!(f, "{}({})", self.trigger, state)
598 } else {
599 write!(f, "{}", self.trigger)
600 }
601 }
602}
603
604#[derive(Debug, PartialEq, Eq, Hash, Clone)]
605pub struct State {
606 pub kind: StateType,
607 pub time: Option<usize>,
608}
609
610impl fmt::Display for State {
611 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
612 if let Some(time) = self.time {
613 write!(f, "{}:{}", self.kind, time)
614 } else {
615 write!(f, "{}", self.kind)
616 }
617 }
618}
619
620#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
621pub struct StateMap {
622 pub states: Vec<State>,
623}
624
625impl StateMap {
626 pub fn new(states: Vec<State>) -> Self {
627 Self { states }
628 }
629
630 pub fn from_map(map: Map) -> Result<Self, Error> {
631 let mut states = vec![];
632 for (k, v) in map.iter() {
633 let mut state = State {
634 kind: StateType::from_str(k)?,
635 time: None,
636 };
637 if let Ok(v) = v.parse::<usize>() {
638 state.time = Some(v);
639 }
640 states.push(state);
641 }
642
643 Ok(StateMap { states })
644 }
645}
646
647impl fmt::Display for StateMap {
648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
649 write!(
650 f,
651 "{}",
652 self.states
653 .iter()
654 .map(|x| x.to_string())
655 .collect::<Vec<_>>()
656 .join(",")
657 )
658 }
659}
660
661#[derive(Debug, PartialEq, Eq, Hash, Clone)]
662pub enum StateType {
663 Press, Hold, Release, Unpressed, UniquePress, UniqueRelease, Analog(usize), Activate, On, Deactivate, Off, }
678
679impl StateType {
680 pub fn phro(&self) -> kll_core::trigger::Phro {
682 match self {
683 StateType::Hold => kll_core::trigger::Phro::Hold,
684 StateType::Off => kll_core::trigger::Phro::Off,
685 StateType::Press => kll_core::trigger::Phro::Press,
686 StateType::Release => kll_core::trigger::Phro::Release,
687 _ => {
688 panic!("Invalid phro StateType: {:?}", self);
689 }
690 }
691 }
692
693 pub fn capability_state(&self) -> kll_core::CapabilityState {
695 match self {
696 StateType::Press => kll_core::CapabilityState::Initial,
697 StateType::Release => kll_core::CapabilityState::Last,
698 _ => {
699 panic!("{:?} not implemented/unsupported", self);
700 }
701 }
702 }
703}
704
705impl FromStr for StateType {
706 type Err = Error;
707
708 fn from_str(s: &str) -> Result<Self, Self::Err> {
709 Ok(match s {
710 "P" => Self::Press,
712 "H" => Self::Hold,
713 "R" => Self::Release,
714 "O" => Self::Unpressed,
715 "UP" => Self::UniquePress,
716 "UR" => Self::UniqueRelease,
717
718 "A" => Self::Activate,
720 "On" => Self::On,
721 "D" => Self::Deactivate,
722 "Off" => Self::Off,
723 _ => {
724 return Err(Error::UnknownMatch { s: s.to_string() });
725 }
726 })
727 }
728}
729
730impl fmt::Display for StateType {
731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732 match self {
733 Self::Press => write!(f, "P"),
735 Self::Hold => write!(f, "H"),
736 Self::Release => write!(f, "R"),
737 Self::Unpressed => write!(f, "O"),
738 Self::UniquePress => write!(f, "UP"),
739 Self::UniqueRelease => write!(f, "UR"),
740 Self::Analog(v) => write!(f, "{}", v),
741
742 Self::Activate => write!(f, "A"),
744 Self::On => write!(f, "On"),
745 Self::Deactivate => write!(f, "D"),
746 Self::Off => write!(f, "Off"),
747 }
748 }
749}
750
751#[derive(Debug, PartialEq, Eq, Hash, Clone)]
752pub enum Key<'a> {
753 Scancode(usize),
754 Char(&'a str),
755 Usb(&'a str),
756 Consumer(&'a str),
757 System(&'a str),
758 Unicode(&'a str),
759 None,
760}
761
762fn parse_int_option(input: Option<&String>) -> Option<usize> {
764 use crate::parser::parse_int;
765 input.map(|val| parse_int(val))
766}
767
768impl<'a> Key<'a> {
769 pub fn value(&self, layout: &Layout) -> Option<usize> {
770 match self {
771 Key::Scancode(num) => Some(*num),
772 Key::Char(c) => parse_int_option(layout.from_hid_keyboard.get(*c)),
773 Key::Usb(name) => parse_int_option(layout.from_hid_keyboard.get(*name)),
774 Key::Consumer(name) => parse_int_option(layout.from_hid_consumer.get(*name)),
775 Key::System(name) => parse_int_option(layout.from_hid_sysctrl.get(*name)),
776 Key::Unicode(_) => None, Key::None => None,
778 }
779 }
780}
781
782impl<'a> fmt::Display for Key<'a> {
783 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
784 match self {
785 Key::Scancode(num) => write!(f, "S{}", num),
786 Key::Char(num) => write!(f, "'{}'", num),
787 Key::Usb(name) => write!(f, "U\"{}\"", name),
788 Key::Consumer(name) => write!(f, "CONS\"{}\"", name),
789 Key::System(name) => write!(f, "SYS\"{}\"", name),
790 Key::Unicode(name) => write!(f, "U+{}", name),
791 Key::None => write!(f, "None"),
792 }
793 }
794}
795
796#[derive(Debug, PartialEq, Eq, Hash, Clone)]
797pub enum ResultType<'a> {
798 Output(Key<'a>),
799 Layer((LayerMode, Indices)),
800 Animation(AnimationResult<'a>),
801 Pixel(Pixel<'a>),
802 PixelLayer(Pixel<'a>),
803 Capability((Capability<'a>, Option<StateMap>)),
804 Text(&'a str),
805 UnicodeText(&'a str),
806 NOP,
807}
808
809impl<'a> fmt::Display for ResultType<'a> {
810 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
811 match self {
812 Self::Output(trigger) => write!(f, "{}", trigger),
813 Self::Layer((mode, layers)) => write!(f, "{}[{}]", mode, format_indices(layers)),
814 Self::Animation(trigger) => write!(f, "{}", trigger),
815 Self::Pixel(trigger) => write!(f, "{}", trigger),
816 Self::PixelLayer(trigger) => write!(f, "{}", trigger),
817 Self::Capability((trigger, state)) => {
818 if let Some(state) = state {
819 write!(f, "{}({})", trigger, state)
820 } else {
821 write!(f, "{}", trigger)
822 }
823 }
824 Self::Text(text) => write!(f, "\"{}\"", text),
825 Self::UnicodeText(text) => write!(f, "u\"{}\"", text),
826 Self::NOP => write!(f, "None"),
827 }
828 }
829}
830
831#[derive(Debug, PartialEq, Eq, Hash, Clone)]
832pub struct Action<'a> {
833 pub result: ResultType<'a>,
834 pub state: Option<StateMap>,
835}
836
837impl<'a> Action<'a> {
838 pub fn kll_core_condition(&self, layouts: &mut Layouts) -> kll_core::Capability {
840 assert!(self.state.is_some(), "state *must* be defined, use generate_state_scheduling() to convert implied state into implicit state.");
844 assert!(self.state.as_ref().unwrap().states.len() == 1, "StateMap *must* only have a single state defined, need to expand into a sequence first.");
845
846 let layout = layouts.get_layout("base/base.json");
847 match &self.result {
848 ResultType::Output(key) => {
849 let id = match key.value(&layout) {
850 Some(id) => id,
851 None => {
852 panic!("{:?} doesn't match a USB HID key.", key);
853 }
854 };
855 match key {
856 Key::Usb(_value) => {
857 kll_core::Capability::HidKeyboard {
858 state: self.state.as_ref().unwrap().states[0]
859 .kind
860 .capability_state(),
861 loop_condition_index: 0, id: kll_core::kll_hid::Keyboard::from(id as u16),
863 }
864 }
865 _ => kll_core::Capability::NoOp {
866 state: kll_core::CapabilityState::None,
867 loop_condition_index: 0,
868 },
869 }
870 }
871 ResultType::Layer((_mode, _indices)) => {
872 panic!("Incomplete {:?}", &self.result);
873 }
874 ResultType::Animation(_animation_result) => {
875 panic!("Incomplete {:?}", &self.result);
876 }
877 ResultType::Capability((_capability, _state)) => {
878 panic!("Incomplete {:?}", &self.result);
879 }
880 ResultType::Text(_text) => {
881 panic!("Incomplete {:?}", &self.result);
882 }
883 ResultType::UnicodeText(_text) => {
884 panic!("Incomplete {:?}", &self.result);
885 }
886 ResultType::NOP => kll_core::Capability::NoOp {
887 state: kll_core::CapabilityState::None,
888 loop_condition_index: 0,
889 },
890 _ => {
891 panic!("Incomplete {:?}", &self.result);
892 }
893 }
894 }
895
896 fn implied_state(&self) -> Option<Vec<Self>> {
901 if self.state.is_none() {
903 Some(vec![
904 Self {
905 result: self.result.clone(),
906 state: Some(StateMap::new(vec![State {
907 kind: StateType::Press,
908 time: None,
909 }])),
910 },
911 Self {
912 result: self.result.clone(),
913 state: Some(StateMap::new(vec![State {
914 kind: StateType::Release,
915 time: None,
916 }])),
917 },
918 ])
919 } else {
920 None
921 }
922 }
923}
924
925impl<'a> fmt::Display for Action<'a> {
926 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
927 if let Some(state) = &self.state {
928 write!(f, "{}:{}", self.result, state)
929 } else {
930 write!(f, "{}", self.result)
931 }
932 }
933}
934
935#[derive(Debug, PartialEq, Eq, Hash, Clone)]
936pub enum TriggerMode {
937 Replace, SoftReplace, Add, Remove, IsolateReplace, IsolateSoftReplace, IsolateAdd, IsolateRemove, }
946
947impl FromStr for TriggerMode {
948 type Err = Error;
949
950 fn from_str(s: &str) -> Result<Self, Self::Err> {
951 Ok(match s {
952 ":" => Self::Replace,
953 "::" => Self::SoftReplace,
954 ":+" => Self::Add,
955 ":-" => Self::Remove,
956 "i:" => Self::IsolateReplace,
957 "i::" => Self::IsolateSoftReplace,
958 "i:+" => Self::IsolateAdd,
959 "i:-" => Self::IsolateRemove,
960 _ => {
961 return Err(Error::UnknownMatch { s: s.to_string() });
962 }
963 })
964 }
965}
966
967impl fmt::Display for TriggerMode {
968 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
969 match self {
970 Self::Replace => write!(f, ":"),
971 Self::SoftReplace => write!(f, "::"),
972 Self::Add => write!(f, ":+"),
973 Self::Remove => write!(f, ":-"),
974 Self::IsolateReplace => write!(f, "i:"),
975 Self::IsolateSoftReplace => write!(f, "i::"),
976 Self::IsolateAdd => write!(f, "i:+"),
977 Self::IsolateRemove => write!(f, "i:-"),
978 }
979 }
980}
981
982#[derive(Debug, PartialEq, Eq, Hash, Clone)]
983pub enum PixelAddr {
984 Absolute(usize),
985 RelativeInt(usize),
986 RelativePercent(usize),
987}
988
989impl FromStr for PixelAddr {
990 type Err = <usize as FromStr>::Err;
991
992 fn from_str(s: &str) -> Result<Self, Self::Err> {
993 Ok(PixelAddr::Absolute(s.parse::<usize>()?))
994 }
995}
996
997impl fmt::Display for PixelAddr {
998 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999 match self {
1000 Self::Absolute(v) => write!(f, "{}", v),
1001 Self::RelativeInt(v) => write!(f, "{:+}", v),
1002 Self::RelativePercent(v) => write!(f, "{:+}%", v),
1003 }
1004 }
1005}
1006
1007#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
1008pub struct PixelRange<'a> {
1009 pub index: Option<PixelAddr>,
1010 pub row: Option<PixelAddr>,
1011 pub col: Option<PixelAddr>,
1012 pub key: Option<Key<'a>>,
1013}
1014
1015impl<'a> PixelRange<'a> {
1016 pub fn from_map(map: Map) -> Result<Self, <usize as FromStr>::Err> {
1017 let mut pos = PixelRange::default();
1018 for (k, v) in map.iter() {
1019 match *k {
1020 "i" => pos.index = Some(PixelAddr::from_str(v)?),
1021 "r" => pos.row = Some(PixelAddr::from_str(v)?),
1022 "c" => pos.col = Some(PixelAddr::from_str(v)?),
1023 _ => {}
1024 }
1025 }
1026
1027 Ok(pos)
1028 }
1029}
1030
1031impl<'a> fmt::Display for PixelRange<'a> {
1032 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1033 if let Some(index) = &self.index {
1034 write!(f, "{}", index)?;
1035 }
1036 if let Some(row) = &self.row {
1037 write!(f, "r:{}", row)?;
1038 }
1039 if let Some(col) = &self.col {
1040 write!(f, "c:{}", col)?;
1041 }
1042 Ok(())
1043 }
1044}
1045
1046#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1047pub struct AnimationResult<'a> {
1048 pub name: &'a str,
1049 pub args: Vec<&'a str>,
1050}
1051
1052impl<'a> fmt::Display for AnimationResult<'a> {
1053 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1054 write!(f, "A[{}]({})", self.name, self.args.join(", "))
1055 }
1056}
1057
1058#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
1059pub struct Pixel<'a> {
1060 pub range: PixelRange<'a>,
1061 pub channel_values: Vec<PixelColor>,
1062}
1063
1064impl<'a> fmt::Display for Pixel<'a> {
1065 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1066 write!(
1067 f,
1068 "P[{}]({})",
1069 self.range,
1070 self.channel_values
1071 .iter()
1072 .map(|x| x.to_string())
1073 .collect::<Vec<String>>()
1074 .join(", ")
1075 )
1076 }
1077}
1078
1079#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1080pub enum PixelColor {
1081 Rgb(usize),
1082 Relative(isize),
1083 RelativeNoRoll(isize),
1084 Shift(isize),
1085}
1086
1087impl fmt::Display for PixelColor {
1088 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1089 match self {
1090 Self::Rgb(v) => write!(f, "{}", v),
1091 Self::Relative(v) => write!(f, "{:+}", v),
1092 Self::RelativeNoRoll(v) => write!(f, ":{:+}", v),
1093 Self::Shift(v) => write!(f, "<{:+}", v),
1094 }
1095 }
1096}
1097
1098#[derive(Debug, Default, Clone)]
1099pub struct KllFile<'a> {
1100 pub statements: Vec<Statement<'a>>,
1101}
1102
1103impl<'a> fmt::Display for KllFile<'a> {
1104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1105 for statement in &self.statements {
1106 writeln!(f, "{}", statement)?;
1107 }
1108 Ok(())
1109 }
1110}