1use crate::input::{GamepadAction, GenericInput, KeyboardInput}; 2use sdl3::mouse::MouseButton; 3use serde::de::{Error, Visitor}; 4use serde::{Deserialize, Deserializer, Serialize, Serializer}; 5use std::fmt::Formatter; 6use std::str::FromStr; 7 8impl Serialize for KeyboardInput { 9 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 10 where 11 S: Serializer, 12 { 13 serializer.serialize_str(&self.serialize_to_str()) 14 } 15} 16 17impl<'de> Deserialize<'de> for KeyboardInput { 18 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 19 where 20 D: Deserializer<'de>, 21 { 22 struct KeyboardInputVisitor; 23 24 impl Visitor<'_> for KeyboardInputVisitor { 25 type Value = KeyboardInput; 26 27 fn expecting(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { 28 write!(formatter, "KeyboardInput") 29 } 30 31 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 32 where 33 E: Error, 34 { 35 let key = KeyboardInput::deserialize_from_str(v).ok_or_else(|| { 36 Error::custom(format!("Invalid keyboard input string: '{v}'")) 37 })?; 38 Ok(key) 39 } 40 } 41 42 deserializer.deserialize_str(KeyboardInputVisitor) 43 } 44}
Serialize GamepadAction as a single string to avoid making the TOML config extremely messy
47struct SerializableGamepadAction(GamepadAction);
49impl Serialize for SerializableGamepadAction { 50 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 51 where 52 S: Serializer, 53 { 54 serializer.serialize_str(&self.0.to_string()) 55 } 56} 57 58impl<'de> Deserialize<'de> for SerializableGamepadAction { 59 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 60 where 61 D: Deserializer<'de>, 62 { 63 struct GamepadActionVisitor; 64 65 impl Visitor<'_> for GamepadActionVisitor { 66 type Value = SerializableGamepadAction; 67 68 fn expecting(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { 69 write!(formatter, "SerializableGamepadAction") 70 } 71 72 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 73 where 74 E: Error, 75 { 76 Ok(SerializableGamepadAction( 77 GamepadAction::from_str(v).map_err(|_| { 78 Error::custom(format!("Invalid gamepad action string: '{v}'")) 79 })?, 80 )) 81 } 82 } 83 84 deserializer.deserialize_str(GamepadActionVisitor) 85 } 86}
Only exists because MouseButton does not implement serde traits
99macro_rules! impl_from_mouse_button { 100 ($a:ty, $b:ty) => { 101 impl From<$a> for $b { 102 fn from(value: $a) -> Self { 103 match value { 104 <$a>::Unknown => Self::Unknown, 105 <$a>::Left => Self::Left, 106 <$a>::Right => Self::Right, 107 <$a>::Middle => Self::Middle, 108 <$a>::X1 => Self::X1, 109 <$a>::X2 => Self::X2, 110 } 111 } 112 } 113 }; 114} 115 116impl_from_mouse_button!(MouseButton, SerializableMouseButton); 117impl_from_mouse_button!(SerializableMouseButton, MouseButton);
Alternate representation of GenericInput that serializes in a nicer format
128impl Serialize for GenericInput { 129 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 130 where 131 S: Serializer, 132 { 133 let serializable = match *self { 134 Self::Keyboard(key) => SerializableGenericInput::Keyboard { key }, 135 Self::Gamepad { gamepad_idx, action } => SerializableGenericInput::Gamepad { 136 gamepad_idx, 137 action: SerializableGamepadAction(action), 138 }, 139 Self::Mouse(button) => SerializableGenericInput::Mouse { button: button.into() }, 140 }; 141 142 serializable.serialize(serializer) 143 } 144} 145 146impl<'de> Deserialize<'de> for GenericInput { 147 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 148 where 149 D: Deserializer<'de>, 150 { 151 let serializable = SerializableGenericInput::deserialize(deserializer)?; 152 153 Ok(match serializable { 154 SerializableGenericInput::Keyboard { key } => Self::Keyboard(key), 155 SerializableGenericInput::Gamepad { gamepad_idx, action } => { 156 Self::Gamepad { gamepad_idx, action: action.0 } 157 } 158 SerializableGenericInput::Mouse { button } => Self::Mouse(button.into()), 159 }) 160 } 161}