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 tcp_server::TcpServer;
16
17type CfgPath = PathBuf;
18
19pub struct ValidatedArgs {
20    pub paths: Vec<CfgPath>,
21    #[cfg(feature = "tcp_server")]
22    pub tcp_server_address: Option<SocketAddrWrapper>,
23    #[cfg(any(target_os = "linux", target_os = "android"))]
24    pub symlink_path: Option<String>,
25    pub nodelay: bool,
26}
27
28pub fn default_cfg() -> Vec<PathBuf> {
29    let mut cfgs = Vec::new();
30
31    let default = PathBuf::from("kanata.kbd");
32    if default.is_file() {
33        cfgs.push(default);
34    }
35
36    if let Some(config_dir) = dirs::config_dir() {
37        let fallback = config_dir.join("kanata").join("kanata.kbd");
38        if fallback.is_file() {
39            cfgs.push(fallback);
40        }
41    }
42
43    cfgs
44}
45
46#[derive(Debug, Clone)]
47pub struct SocketAddrWrapper(SocketAddr);
48
49impl FromStr for SocketAddrWrapper {
50    type Err = Error;
51
52    fn from_str(s: &str) -> Result<Self, Self::Err> {
53        let mut address = s.to_string();
54        if let Ok(port) = s.parse::<u16>() {
55            address = format!("127.0.0.1:{port}");
56        }
57        address
58            .parse::<SocketAddr>()
59            .map(SocketAddrWrapper)
60            .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}"))
61    }
62}
63
64impl SocketAddrWrapper {
65    pub fn into_inner(self) -> SocketAddr {
66        self.0
67    }
68    pub fn get_ref(&self) -> &SocketAddr {
69        &self.0
70    }
71}