rmk_config/
board.rs

1use crate::{InputDeviceConfig, KeyboardTomlConfig, MatrixConfig, MatrixType, SplitConfig};
2
3#[derive(Clone, Debug)]
4pub enum BoardConfig {
5    Split(SplitConfig),
6    UniBody(UniBodyConfig),
7}
8
9#[derive(Clone, Debug, Default)]
10pub struct UniBodyConfig {
11    pub matrix: MatrixConfig,
12    pub input_device: InputDeviceConfig,
13}
14
15impl Default for BoardConfig {
16    fn default() -> Self {
17        BoardConfig::UniBody(UniBodyConfig::default())
18    }
19}
20
21impl BoardConfig {
22    /// Get number of peripherals
23    pub fn get_num_periphreal(&self) -> usize {
24        match self {
25            BoardConfig::Split(split_config) => split_config.peripheral.len(),
26            BoardConfig::UniBody(_) => 0,
27        }
28    }
29    /// Get the number of encoders for each board
30    ///
31    /// - If the board is the unibody board, the returned vector has only one element.
32    /// - If the board is the split board, the number of elements is the number of peripherals + 1 (central),
33    ///   where the first element is the number of encoders on the central.
34    pub fn get_num_encoder(&self) -> Vec<usize> {
35        let mut num_encoder = Vec::new();
36        match self {
37            BoardConfig::Split(split) => {
38                // Central's encoders
39                num_encoder.push(
40                    split
41                        .central
42                        .input_device
43                        .clone()
44                        .unwrap_or_default()
45                        .encoder
46                        .unwrap_or(Vec::new())
47                        .len(),
48                );
49
50                // Peripheral's encoders
51                for peri in &split.peripheral {
52                    num_encoder.push(
53                        peri.input_device
54                            .clone()
55                            .unwrap_or_default()
56                            .encoder
57                            .unwrap_or(Vec::new())
58                            .len(),
59                    );
60                }
61            }
62            BoardConfig::UniBody(uni_body_config) => {
63                num_encoder.push(uni_body_config.input_device.encoder.clone().unwrap_or(Vec::new()).len());
64            }
65        };
66        num_encoder
67    }
68}
69
70impl KeyboardTomlConfig {
71    pub fn get_board_config(&self) -> Result<BoardConfig, String> {
72        let matrix = self.matrix.clone();
73        let split = self.split.clone();
74        let input_device = self.input_device.clone();
75        match (matrix, split) {
76            (None, Some(s)) => {
77                Ok(BoardConfig::Split(s))
78            },
79            (Some(m), None) => {
80                match m.matrix_type {
81                    MatrixType::normal => {
82                        if m.row_pins.is_none() || m.col_pins.is_none() {
83                            return Err("`row_pins` and `col_pins` is required for normal matrix".to_string());
84                        }
85                    },
86                    MatrixType::direct_pin => {
87                        if m.direct_pins.is_none() {
88                            return Err("`direct_pins` is required for direct pin matrix".to_string());
89                        }
90                    },
91                }
92                // FIXME: input device for split keyboard is not supported yet
93                Ok(BoardConfig::UniBody(UniBodyConfig{matrix: m, input_device: input_device.unwrap_or_default()}))
94            },
95            (None, None) => Err("[matrix] section in keyboard.toml is required for non-split keyboard".to_string()),
96            _ => Err("Use at most one of [matrix] or [split] in your keyboard.toml!\n-> [matrix] is used to define a normal matrix of non-split keyboard\n-> [split] is used to define a split keyboard\n".to_string()),
97        }
98    }
99}