// nixos-config - My current NixOS configuration // // Copyright (C) 2025 Benedikt Peetz // SPDX-License-Identifier: GPL-3.0-or-later // // This file is part of my nixos-config. // // You should have received a copy of the License along with this program. // If not, see . use std::{fmt::Display, ops::Deref, str::FromStr}; use anyhow::{anyhow, bail, Context, Result}; use keymaps::{ key_repr::{Key, Keys}, map_tree::MapTrie, }; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; pub mod commands; #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, PartialOrd)] /// What values to use for: `riverctl ` #[serde(deny_unknown_fields)] pub struct KeyConfig { command: Vec, /// Whether to allow this key mapping in the “locked” mode. #[serde(default)] allow_locked: bool, } impl FromStr for KeyMap { type Err = anyhow::Error; fn from_str(s: &str) -> Result { fn decode_value( output: &mut MapTrie, current_key: Vec, value: &Value, ) -> Result<()> { let key_config = if let Some(value) = value.as_array() { KeyConfig { command: value .iter() .map(|v| v.as_str().map(ToOwned::to_owned)) .collect::>() .ok_or(anyhow!("A array contained a non-string value: {value:#?}"))?, allow_locked: false, } } else if let Some(object) = value.as_object() { if object.contains_key("command") { serde_json::from_value(value.to_owned()) .with_context(|| format!("Failed to parse key config: {value:#?}"))? } else { for (key, value) in object { let mut local_current_key = current_key.clone(); local_current_key.push( Key::from_str(key) .with_context(|| format!("Failed to parse key '{key}'"))?, ); decode_value(output, local_current_key, value)?; } return Ok(()); } } else { bail!("Value ({}) is invalid (not array or object).", value) }; output .insert(¤t_key, key_config.clone()) .with_context(|| { format!( "Failed to insert mapping {} -> {key_config}", Keys::from(current_key) ) })?; Ok(()) } let mut out = MapTrie::::new(); let raw: Map = serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?; for (key, value) in raw { decode_value( &mut out, vec![Key::from_str(&key) .with_context(|| format!("Failed to parse key ('{key}')"))?], &value, )?; } Ok(Self(out)) } } impl Display for KeyConfig { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(self.command.join(" ").as_str()) } } #[derive(Debug)] pub struct KeyMap(MapTrie); impl Display for KeyMap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) } } impl Deref for KeyMap { type Target = MapTrie; fn deref(&self) -> &Self::Target { &self.0 } }