Skip to content

Commit

Permalink
config: Handle unknown Action/SystemAction gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Jan 22, 2025
1 parent fe529ae commit 9c59924
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 7 deletions.
18 changes: 16 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ serde_with = "3.9.0"
thiserror = "1.0.64"
tracing = "0.1.40"
xkbcommon = "0.7.0"
ron = "0.9.0-alpha.0"
99 changes: 94 additions & 5 deletions config/src/shortcuts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ pub fn system_actions(context: &cosmic_config::Config) -> SystemActions {

// Get the system config first
if let Ok(context) = cosmic_config::Config::system(ID, Config::VERSION) {
match context.get::<SystemActions>("system_actions") {
Ok(system_config) => config = system_config,
match context.get::<SystemActionsImpl>("system_actions") {
Ok(system_config) => config = system_config.0,
Err(why) => {
tracing::error!("failed to read system shortcuts config 'system_actions': {why:?}");
}
}
}

// Then override it with the user's config
match context.get::<SystemActions>("system_actions") {
Ok(user_config) => config.extend(user_config),
match context.get::<SystemActionsImpl>("system_actions") {
Ok(user_config) => config.extend(user_config.0),
Err(why) => {
tracing::error!("failed to read local shortcuts config 'system_actions': {why:?}");
}
Expand Down Expand Up @@ -100,10 +100,54 @@ impl Config {
}

/// A map of defined key [Binding]s and their triggerable [Action]s
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[serde(transparent)]
pub struct Shortcuts(pub HashMap<Binding, Action>);

struct ShortcutMapVisitor;

impl<'de> serde::de::Visitor<'de> for ShortcutMapVisitor {
type Value = Shortcuts;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Shortcuts Map")
}

fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: serde::de::MapAccess<'de>,
{
let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0));

while let Some((binding, action)) = access.next_entry::<Binding, &ron::value::RawValue>()? {
match action.into_rust::<Action>() {
Ok(val) => {
map.insert(binding, val);
}
Err(err) => {
tracing::warn!(
"Skipping over invalid Action ({}): {}",
action.get_ron(),
err
);
map.insert(binding, Action::Disable);
}
};
}

Ok(Shortcuts(map))
}
}

impl<'de> Deserialize<'de> for Shortcuts {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserializer.deserialize_map(ShortcutMapVisitor)
}
}

impl Shortcuts {
// pub fn default_shortcuts() -> Self {
// Shortcuts(HashMap::from([
Expand Down Expand Up @@ -172,3 +216,48 @@ pub enum State {
Pressed,
Released,
}

pub struct SystemActionsImpl(SystemActions);

struct SystemActionsMapVisitor;

impl<'de> serde::de::Visitor<'de> for SystemActionsMapVisitor {
type Value = SystemActionsImpl;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("SystemActions Map")
}

fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: serde::de::MapAccess<'de>,
{
let mut map = BTreeMap::new();

while let Some((action, command)) = access.next_entry::<&ron::value::RawValue, String>()? {
match action.into_rust::<action::System>() {
Ok(val) => {
map.insert(val, command);
}
Err(err) => {
tracing::warn!(
"Skipping over invalid SystemAction ({}): {}",
action.get_ron(),
err
);
}
};
}

Ok(SystemActionsImpl(map))
}
}

impl<'de> Deserialize<'de> for SystemActionsImpl {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserializer.deserialize_map(SystemActionsMapVisitor)
}
}

0 comments on commit 9c59924

Please sign in to comment.