rktk/config/mod.rs
1//! Rktk configuration management.
2//!
3//! # Overview of config
4//!
5//! The overall picture of rktk's configuration is shown below. Some can be configured by JSON files only, some by Rust code only, and some by both.
6//!
7//! ```text
8//! rktk config
9//! ├─ RktkOpts <── Root option structure that is passed to the start function
10//! │ ├─ config <── This is "dynamic config". Can be set by both json and code
11//! │ ├─ keymap ┐
12//! │ ├─ display ├── Must be defined by the code
13//! │ ├─ ... (Other opts) ┘
14//! ├─ CONST_CONFIG <── This is "constant config". Automatically loaded from json file
15//! ```
16//!
17//! # JSON file
18//!
19//! rktk uses a JSON file as the main config file. This JSON file is read at compile time from the path set in the `RKTK_CONFIG_PATH` environment variable.
20//! This file allows both const config and dynamic config, with the difference that const config can only be configured in this file, while dynamic config is not.
21//! Also, const config is used automatically, whereas dynamic config is not (see the `Dynamic config` section for details)
22//!
23//! You can configure your keyboard crate (bin crate) to use the `rktk.json` file in the project root by setting the following in `.cargo/config.toml`.
24//! The file name can be anything, but we recommend `rktk.json` for clarity.
25//!
26//! ```toml
27//! [env]
28//! RKTK_CONFIG_PATH = { value = "rktk.json", relative = true }
29//! ```
30//!
31//! Here is the example of the `rktk.json` file.
32//! ```json
33//! {
34//! "$schema": "https://raw.githubusercontent.com/nazo6/rktk/refs/heads/master/lib/rktk/schema.json",
35//! "constant": {
36//! "keyboard": {
37//! "cols": 12,
38//! "rows": 4,
39//! }
40//! },
41//! "dynamic": {
42//! "keyboard": {
43//! "name": "corne",
44//! }
45//! }
46//! }
47//! ```
48//!
49//! The rktk json config is divided into two parts: const config and dynamic config.
50//!
51//! ## Constant config
52//! The “const” config, as the name implies, is a config that sets constants and is used for values that need to be determined at compile time, such as buffer size.
53//! This config can only be set by a json file set via `RKTK_CONFIG_PATH`, and the loaded values are in the [`CONST_CONFIG`].
54//! The contents of config can be checked at [`schema::ConstantConfig`].
55//!
56//! ## Dynamic config
57//! In contrast to const config, dynamic config is a config that can be configured at runtime.
58//! Like const config, this config can be configured in a json file, but you can also define your own values in the rust code.
59//!
60//! This config can be used by putting it into the config property of the [`RktkOpts`] structure passed as the opts parameter of [`crate::task::start`].
61//!
62//! The dynamic config value obtained from the JSON file is assigned to [`DYNAMIC_CONFIG_FROM_FILE`].
63//! The [`new_rktk_opts`] function can be used to initialize [`RktkOpts`] with this value,
64//! but it is also possible to define your own RktkOpts by not using the JSON file value at all, or by editing some of it.
65//!
66//! For each configuration, see the [`schema::ConstantConfig`] and [`schema::DynamicConfig`] struct.
67//!
68//! # Storage
69//!
70//! In addition to the above programmatic config, config may also be loaded from storage.
71//! Configuration is written to storage via rrp or other actions.
72//! If the configuration is found in storage at startup, the above config will be overwritten with the contents of storage.
73
74use crate::task::display::default_display::DefaultDisplayConfig;
75
76include!(concat!(env!("OUT_DIR"), "/config.rs"));
77
78pub mod keymap;
79pub mod rgb;
80pub mod storage;
81
82/// rktk launch options.
83///
84/// Some properties of this struct requires `'static` lifetime. Even if the value you want to use
85/// is not statically defined, you can obtain static lifetime using [`static_cell`] crate.
86pub struct RktkOpts<D: crate::task::display::DisplayConfig, R: blinksy::layout::Layout2d> {
87 /// Keymap of keyboard
88 pub keymap: &'static keymap::Keymap,
89 /// "dynamic" config
90 pub config: &'static schema::DynamicConfig,
91 /// Display layout
92 pub display: D,
93 pub rgb_layout: R,
94 /// Hand of the keyboard. This is used for split keyboard. For non-split keyboard, set this
95 /// value to `None`.
96 ///
97 /// If `None` is set, [`Hand::Left`] will be used.
98 pub hand: Option<Hand>,
99}
100
101/// Creates a new [`RktkOpts`] with the default display config and the dynamic config loaded from
102/// the JSON file.
103pub fn new_rktk_opts(
104 keymap: &'static keymap::Keymap,
105 hand: Option<Hand>,
106) -> RktkOpts<DefaultDisplayConfig, rgb::DummyLayout> {
107 RktkOpts {
108 keymap,
109 config: &DYNAMIC_CONFIG_FROM_FILE,
110 display: DefaultDisplayConfig,
111 rgb_layout: rgb::DummyLayout,
112 hand,
113 }
114}
115
116#[derive(Clone, Copy, PartialEq, Eq, Debug)]
117pub enum Hand {
118 Left,
119 Right,
120}
121
122impl Hand {
123 pub fn other(&self) -> Hand {
124 match self {
125 Hand::Left => Hand::Right,
126 Hand::Right => Hand::Left,
127 }
128 }
129}