Skip to content

Commit

Permalink
rebase config
Browse files Browse the repository at this point in the history
  • Loading branch information
zzeneg committed Oct 4, 2024
1 parent b0d84f1 commit 6ca105b
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 25 deletions.
38 changes: 30 additions & 8 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
use std::path::PathBuf;
use std::{path::PathBuf, sync::OnceLock};

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
pub devices: Vec<Device>,
pub layouts: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reconnect_delay: Option<u64>,
}

#[derive(serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Device {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(deserialize_with = "string_to_hex")]
#[serde(serialize_with = "hex_to_string", deserialize_with = "string_to_hex")]
pub product_id: u16,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage_page: Option<u16>,
}

pub fn get_config(maybe_path: Option<PathBuf>) -> Config {
static CONFIG: OnceLock<Config> = OnceLock::new();

pub fn get_config() -> &'static Config {
CONFIG.get().unwrap()
}

pub fn load_config(path: PathBuf) -> &'static Config {
if let Some(config) = CONFIG.get() {
return config;
}

let default_config = Config {
devices: vec![Device {
name: None,
Expand All @@ -30,19 +44,20 @@ pub fn get_config(maybe_path: Option<PathBuf>) -> Config {
reconnect_delay: None,
};

let path = maybe_path.unwrap_or("./qmk-hid-host.json".into());

if let Ok(file) = std::fs::read_to_string(&path) {
return serde_json::from_str::<Config>(&file)
let config = serde_json::from_str::<Config>(&file)
.map_err(|e| tracing::error!("Incorrect config file: {}", e))
.unwrap();
return CONFIG.get_or_init(|| config);
}

let file_content = serde_json::to_string_pretty(&default_config).unwrap();
std::fs::write(&path, &file_content).unwrap();
std::fs::write(&path, &file_content)
.map_err(|e| tracing::error!("Error while saving config file to {:?}: {}", path, e))
.unwrap();
tracing::info!("New config file created at {:?}", path);

return default_config;
CONFIG.get_or_init(|| default_config)
}

fn string_to_hex<'de, D>(deserializer: D) -> Result<u16, D::Error>
Expand All @@ -53,3 +68,10 @@ where
let hex = value.trim_start_matches("0x");
return u16::from_str_radix(hex, 16).map_err(serde::de::Error::custom);
}

fn hex_to_string<S>(value: &u16, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("0x{:04x}", value))
}
4 changes: 2 additions & 2 deletions src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ pub struct Keyboard {
}

impl Keyboard {
pub fn new(device: Device, reconnect_delay: u64) -> Self {
pub fn new(device: &Device, reconnect_delay: u64) -> Self {
return Self {
name: device.name.unwrap_or("keyboard".to_string()),
name: device.name.clone().unwrap_or("keyboard".to_string()),
product_id: device.product_id,
usage: device.usage.unwrap_or(0x61),
usage_page: device.usage_page.unwrap_or(0xff60),
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod data_type;
mod keyboard;
mod providers;

use config::get_config;
use config::load_config;
use keyboard::Keyboard;
use providers::{_base::Provider, layout::LayoutProvider, time::TimeProvider, volume::VolumeProvider};
use std::thread;
Expand Down Expand Up @@ -37,12 +37,12 @@ fn main() {
let _ = tracing::subscriber::set_global_default(tracing_subscriber);

let args = Args::parse();
let config = get_config(args.config);
let config = load_config(args.config.unwrap_or("./qmk-hid-host.json".into()));

let (data_sender, _) = broadcast::channel::<Vec<u8>>(1);
let (is_connected_sender, is_connected_receiver) = mpsc::channel::<bool>(1);

for device in config.devices {
for device in &config.devices {
let data_sender = data_sender.clone();
let is_connected_sender = is_connected_sender.clone();
let reconnect_delay = config.reconnect_delay.unwrap_or(5000);
Expand Down
6 changes: 2 additions & 4 deletions src/providers/layout/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ fn send_data(value: &String, layouts: &Vec<String>, data_sender: &broadcast::Sen

pub struct LayoutProvider {
data_sender: broadcast::Sender<Vec<u8>>,
layouts: Vec<String>,
is_started: Arc<AtomicBool>,
}

impl LayoutProvider {
pub fn new(data_sender: broadcast::Sender<Vec<u8>>) -> Box<dyn Provider> {
let provider = LayoutProvider {
data_sender,
layouts: get_config().layouts,
is_started: Arc::new(AtomicBool::new(false)),
};
return Box::new(provider);
Expand All @@ -57,8 +55,8 @@ impl Provider for LayoutProvider {
fn start(&self) {
tracing::info!("Layout Provider started");
self.is_started.store(true, Relaxed);
let layouts = &get_config().layouts;
let data_sender = self.data_sender.clone();
let layouts = self.layouts.clone();
let is_started = self.is_started.clone();
std::thread::spawn(move || {
let mut synced_layout = 0;
Expand All @@ -77,7 +75,7 @@ impl Provider for LayoutProvider {
synced_layout = layout;
let layout_symbol = symbol_list.get(layout + 1).map(|x| x.to_string()).unwrap_or_default();
let layout_name = layout_symbol.split([':', '(']).next().unwrap_or_default().to_string();
send_data(&layout_name, &layouts, &data_sender);
send_data(&layout_name, layouts, &data_sender);
}

std::thread::sleep(std::time::Duration::from_millis(100));
Expand Down
6 changes: 2 additions & 4 deletions src/providers/layout/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,13 @@ fn send_data(value: &String, layouts: &Vec<String>, data_sender: &broadcast::Sen

pub struct LayoutProvider {
data_sender: broadcast::Sender<Vec<u8>>,
layouts: Vec<String>,
is_started: Arc<AtomicBool>,
}

impl LayoutProvider {
pub fn new(data_sender: broadcast::Sender<Vec<u8>>) -> Box<dyn Provider> {
let provider = LayoutProvider {
data_sender,
layouts: get_config().layouts,
is_started: Arc::new(AtomicBool::new(false)),
};
Box::new(provider)
Expand All @@ -72,8 +70,8 @@ impl Provider for LayoutProvider {
fn start(&self) {
tracing::info!("Layout Provider started");
self.is_started.store(true, Relaxed);
let layouts = &get_config().layouts;
let data_sender = self.data_sender.clone();
let layouts = self.layouts.clone();
let is_started = self.is_started.clone();
let mut synced_layout = "".to_string();

Expand All @@ -86,7 +84,7 @@ impl Provider for LayoutProvider {
let lang = layout.split('.').last().unwrap().to_string();
if synced_layout != lang {
synced_layout = lang;
send_data(&synced_layout, &layouts, &data_sender);
send_data(&synced_layout, layouts, &data_sender);
}
}
std::thread::sleep(std::time::Duration::from_millis(100));
Expand Down
6 changes: 2 additions & 4 deletions src/providers/layout/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ fn send_data(value: &String, layouts: &Vec<String>, data_sender: &broadcast::Sen

pub struct LayoutProvider {
data_sender: broadcast::Sender<Vec<u8>>,
layouts: Vec<String>,
is_started: Arc<AtomicBool>,
}

impl LayoutProvider {
pub fn new(data_sender: broadcast::Sender<Vec<u8>>) -> Box<dyn Provider> {
let provider = LayoutProvider {
data_sender,
layouts: get_config().layouts,
is_started: Arc::new(AtomicBool::new(false)),
};
return Box::new(provider);
Expand All @@ -57,8 +55,8 @@ impl Provider for LayoutProvider {
fn start(&self) {
tracing::info!("Layout Provider started");
self.is_started.store(true, Relaxed);
let layouts = &get_config().layouts;
let data_sender = self.data_sender.clone();
let layouts = self.layouts.clone();
let is_started = self.is_started.clone();
std::thread::spawn(move || {
let mut synced_layout = "".to_string();
Expand All @@ -70,7 +68,7 @@ impl Provider for LayoutProvider {
if let Some(layout) = unsafe { get_layout() } {
if synced_layout != layout {
synced_layout = layout;
send_data(&synced_layout, &layouts, &data_sender);
send_data(&synced_layout, layouts, &data_sender);
}
}

Expand Down

0 comments on commit 6ca105b

Please sign in to comment.