Skip to main content

kanata_state_machine/
lib.rs

1use anyhow::{Error, Result, anyhow};
2use std::net::SocketAddr;
3use std::path::PathBuf;
4use std::str::FromStr;
5
6#[cfg(all(target_os = "windows", feature = "gui"))]
7pub mod gui;
8pub mod kanata;
9pub mod oskbd;
10pub mod tcp_server;
11#[cfg(test)]
12pub mod tests;
13
14pub use kanata::*;
15pub use kanata_parser::cfg::FAKE_KEY_ROW;
16pub use kanata_parser::custom_action::FakeKeyAction;
17pub use tcp_server::TcpServer;
18
19type CfgPath = PathBuf;
20
21pub struct ValidatedArgs {
22    pub paths: Vec<CfgPath>,
23    #[cfg(feature = "tcp_server")]
24    pub tcp_server_address: Option<SocketAddrWrapper>,
25    #[cfg(any(target_os = "linux", target_os = "android"))]
26    pub symlink_path: Option<String>,
27    pub nodelay: bool,
28}
29
30pub fn default_cfg() -> Vec<PathBuf> {
31    let mut cfgs = Vec::new();
32
33    let default = PathBuf::from("kanata.kbd");
34    if default.is_file() {
35        cfgs.push(default);
36    }
37
38    if let Some(config_dir) = dirs::config_dir() {
39        let fallback = config_dir.join("kanata").join("kanata.kbd");
40        if fallback.is_file() {
41            cfgs.push(fallback);
42        }
43    }
44
45    cfgs
46}
47
48#[derive(Debug, Clone)]
49pub struct SocketAddrWrapper(SocketAddr);
50
51impl FromStr for SocketAddrWrapper {
52    type Err = Error;
53
54    fn from_str(s: &str) -> Result<Self, Self::Err> {
55        let mut address = s.to_string();
56        if let Ok(port) = s.parse::<u16>() {
57            address = format!("127.0.0.1:{port}");
58        }
59        address
60            .parse::<SocketAddr>()
61            .map(SocketAddrWrapper)
62            .map_err(|e| anyhow!("Please specify either a port number, e.g. 8081 or an address, e.g. 127.0.0.1:8081.\n{e}"))
63    }
64}
65
66impl SocketAddrWrapper {
67    pub fn into_inner(self) -> SocketAddr {
68        self.0
69    }
70    pub fn get_ref(&self) -> &SocketAddr {
71        &self.0
72    }
73}