Merge pull request #927 from Demonthos/more-resilient-key-deserialization

More resilient keyboard event deserialization
This commit is contained in:
Jon Kelley 2023-04-05 13:07:23 -07:00 committed by GitHub
commit 9c7b6d7ed0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,6 +5,16 @@ use std::convert::TryInto;
use std::fmt::{Debug, Formatter};
use std::str::FromStr;
#[cfg(feature = "serialize")]
fn resilient_deserialize_code<'de, D>(deserializer: D) -> Result<Code, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
// If we fail to deserialize the code for any reason, just return Unidentified instead of failing.
Ok(Code::deserialize(deserializer).unwrap_or(Code::Unidentified))
}
pub type KeyboardEvent = Event<KeyboardData>;
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, PartialEq, Eq)]
@ -27,6 +37,10 @@ pub struct KeyboardData {
pub key_code: KeyCode,
/// the physical key on the keyboard
#[cfg_attr(
feature = "serialize",
serde(deserialize_with = "resilient_deserialize_code")
)]
code: Code,
/// Indicate if the `alt` modifier key was pressed during this keyboard event
@ -102,7 +116,7 @@ impl KeyboardData {
/// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
pub fn key(&self) -> Key {
#[allow(deprecated)]
FromStr::from_str(&self.key).expect("could not parse")
FromStr::from_str(&self.key).unwrap_or(Key::Unidentified)
}
/// A physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.
@ -158,10 +172,24 @@ impl Debug for KeyboardData {
}
}
#[cfg_attr(
feature = "serialize",
derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
)]
#[cfg(feature = "serialize")]
impl<'de> serde::Deserialize<'de> for KeyCode {
fn deserialize<D>(deserializer: D) -> Result<KeyCode, D::Error>
where
D: serde::Deserializer<'de>,
{
// We could be deserializing a unicode character, so we need to use u64 even if the output only takes u8
let value = u64::deserialize(deserializer)?;
if let Ok(smaller_uint) = value.try_into() {
Ok(KeyCode::from_raw_code(smaller_uint))
} else {
Ok(KeyCode::Unknown)
}
}
}
#[cfg_attr(feature = "serialize", derive(serde_repr::Serialize_repr))]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum KeyCode {
@ -525,7 +553,6 @@ pub enum KeyCode {
// kanji, = 244
// unlock trackpad (Chrome/Edge), = 251
// toggle touchpad, = 255
#[cfg_attr(feature = "serialize", serde(other))]
Unknown,
}