kanata_state_machine/
lib.rs1use 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}