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 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}