Skip to content

Commit

Permalink
Implement common Std traits on many types (#3796)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda authored Aug 7, 2024
1 parent 9dff801 commit 1168cd4
Show file tree
Hide file tree
Showing 28 changed files with 167 additions and 103 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ android-native-activity = ["android-activity/native-activity"]
default = ["rwh_06", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
mint = ["dpi/mint"]
rwh_06 = ["dep:rwh_06", "ndk/rwh_06"]
serde = ["dep:serde", "cursor-icon/serde", "smol_str/serde", "dpi/serde"]
serde = ["dep:serde", "cursor-icon/serde", "smol_str/serde", "dpi/serde", "bitflags/serde"]
wayland = [
"wayland-client",
"wayland-backend",
Expand Down
3 changes: 3 additions & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ changelog entry.
- Add `Touch::finger_id` with a new type `FingerId`.
- On Web and Windows, add `FingerIdExt*::is_primary()`, exposing a way to determine
the primary finger in a multi-touch interaction.
- Implement `Clone`, `Copy`, `Debug`, `Deserialize`, `Eq`, `Hash`, `Ord`, `PartialEq`, `PartialOrd`
and `Serialize` on many types.

### Changed

Expand Down Expand Up @@ -91,6 +93,7 @@ changelog entry.
- On Web, `CursorGrabMode::Locked` now lets `DeviceEvent::MouseMotion` return raw data, not OS
accelerated, if the browser supports it.
- `(Active)EventLoop::create_custom_cursor()` now returns a `Result<CustomCursor, ExternalError>`.
- Changed how `ModifiersState` is serialized by Serde.

### Removed

Expand Down
9 changes: 5 additions & 4 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,16 @@ impl CustomCursor {
/// Source for [`CustomCursor`].
///
/// See [`CustomCursor`] for more details.
#[derive(Debug)]
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct CustomCursorSource {
// Some platforms don't support custom cursors.
#[allow(dead_code)]
pub(crate) inner: PlatformCustomCursorSource,
}

/// An error produced when using [`CustomCursor::from_rgba`] with invalid arguments.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum BadImage {
/// Produced when the image dimensions are larger than [`MAX_CURSOR_SIZE`]. This doesn't
/// guarantee that the cursor will work, but should avoid many platform and device specific
Expand Down Expand Up @@ -166,7 +167,7 @@ impl Error for BadImage {}
/// Platforms export this directly as `PlatformCustomCursorSource` if they need to only work with
/// images.
#[allow(dead_code)]
#[derive(Debug)]
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub(crate) struct OnlyCursorImageSource(pub(crate) CursorImage);

#[allow(dead_code)]
Expand Down Expand Up @@ -201,7 +202,7 @@ impl PartialEq for OnlyCursorImage {

impl Eq for OnlyCursorImage {}

#[derive(Debug)]
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
#[allow(dead_code)]
pub(crate) struct CursorImage {
pub(crate) rgba: Vec<u8>,
Expand Down
3 changes: 2 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ pub enum ExternalError {
}

/// The error type for when the requested operation is not supported by the backend.
#[derive(Clone)]
#[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NotSupportedError {
_marker: (),
}
Expand Down
18 changes: 14 additions & 4 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub(crate) enum Event {
}

/// Describes the reason the event loop is resuming.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StartCause {
/// Sent if the time specified by [`ControlFlow::WaitUntil`] has been reached. Contains the
/// moment the timeout was requested and the requested resume time. The actual resume time is
Expand Down Expand Up @@ -434,6 +434,12 @@ pub enum WindowEvent {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId(pub(crate) platform_impl::DeviceId);

impl Default for DeviceId {
fn default() -> Self {
Self::dummy()
}
}

impl DeviceId {
/// Returns a dummy id, useful for unit testing.
///
Expand Down Expand Up @@ -475,7 +481,7 @@ impl FingerId {
/// (corresponding to GUI cursors and keyboard focus) the device IDs may not match.
///
/// Note that these events are delivered regardless of input focus.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum DeviceEvent {
/// Change in physical position of a pointing device.
///
Expand Down Expand Up @@ -524,7 +530,7 @@ pub enum DeviceEvent {
/// repeat or the initial keypress. An application may emulate this by, for
/// example keeping a Map/Set of pressed keys and determining whether a keypress
/// corresponds to an already pressed key.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RawKeyEvent {
pub physical_key: keyboard::PhysicalKey,
Expand Down Expand Up @@ -669,7 +675,8 @@ pub struct KeyEvent {
}

/// Describes keyboard modifiers event.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Modifiers {
pub(crate) state: ModifiersState,

Expand Down Expand Up @@ -871,6 +878,7 @@ pub struct Touch {

/// Describes the force of a touch event
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Force {
/// On iOS, the force is calibrated so that the same number corresponds to
/// roughly the same amount of pressure on the screen regardless of the
Expand Down Expand Up @@ -1020,6 +1028,8 @@ impl PartialEq for InnerSizeWriter {
}
}

impl Eq for InnerSizeWriter {}

#[cfg(test)]
mod tests {
use std::collections::{BTreeSet, HashSet};
Expand Down
19 changes: 13 additions & 6 deletions src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct EventLoop {
/// easier. But note that constructing multiple event loops is not supported.
///
/// This can be created using [`EventLoop::builder`].
#[derive(Default)]
#[derive(Default, PartialEq, Eq, Hash)]
pub struct EventLoopBuilder {
pub(crate) platform_specific: platform_impl::PlatformSpecificEventLoopAttributes,
}
Expand Down Expand Up @@ -115,9 +115,15 @@ impl EventLoopBuilder {
}
}

impl fmt::Debug for EventLoopBuilder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("EventLoopBuilder").finish_non_exhaustive()
}
}

impl fmt::Debug for EventLoop {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("EventLoop { .. }")
f.debug_struct("EventLoop").finish_non_exhaustive()
}
}

Expand All @@ -129,7 +135,7 @@ impl fmt::Debug for EventLoop {
///
/// [`Wait`]: Self::Wait
/// [`about_to_wait`]: crate::application::ApplicationHandler::about_to_wait
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub enum ControlFlow {
/// When the current loop iteration finishes, immediately begin a new iteration regardless of
/// whether or not new events are available to process.
Expand Down Expand Up @@ -419,7 +425,7 @@ pub trait ActiveEventLoop {
///
/// - A zero-sized type that is likely optimized out.
/// - A reference-counted pointer to the underlying type.
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
pub struct OwnedDisplayHandle {
#[cfg_attr(not(feature = "rwh_06"), allow(dead_code))]
pub(crate) platform: platform_impl::OwnedDisplayHandle,
Expand Down Expand Up @@ -474,12 +480,13 @@ impl EventLoopProxy {

impl fmt::Debug for EventLoopProxy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("EventLoopProxy { .. }")
f.debug_struct("ActiveEventLoop").finish_non_exhaustive()
}
}

/// Control when device events are captured.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum DeviceEvents {
/// Report device events regardless of window focus.
Always,
Expand All @@ -499,7 +506,7 @@ pub enum DeviceEvents {
/// containing [`AsyncRequestSerial`] and some closure associated with it.
/// Then once event is arriving the working list is being traversed and a job
/// executed and removed from the list.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AsyncRequestSerial {
serial: usize,
}
Expand Down
6 changes: 3 additions & 3 deletions src/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ impl fmt::Display for BadIcon {

impl Error for BadIcon {}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct RgbaIcon {
pub(crate) rgba: Vec<u8>,
pub(crate) width: u32,
pub(crate) height: u32,
}

/// For platforms which don't have window icons (e.g. Web)
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct NoIcon;

#[allow(dead_code)] // These are not used on every platform
Expand Down Expand Up @@ -94,7 +94,7 @@ mod constructors {
}

/// An icon used for the window titlebar, taskbar, etc.
#[derive(Clone)]
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct Icon {
pub(crate) inner: PlatformIcon,
}
Expand Down
55 changes: 5 additions & 50 deletions src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ impl Key {
///
/// [`location`]: ../event/struct.KeyEvent.html#structfield.location
/// [`KeyEvent`]: crate::event::KeyEvent
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum KeyLocation {
/// The key is in its "normal" location on the keyboard.
Expand Down Expand Up @@ -1700,6 +1700,7 @@ bitflags! {
///
/// Each flag represents a modifier and is set if this modifier is active.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ModifiersState: u32 {
/// The "shift" key.
const SHIFT = 0b100;
Expand Down Expand Up @@ -1735,7 +1736,8 @@ impl ModifiersState {
}

/// The state of the particular modifiers key.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ModifiersKeyState {
/// The particular key is pressed.
Pressed,
Expand All @@ -1754,6 +1756,7 @@ pub enum ModifiersKeyState {
// on macOS due to their AltGr/Option situation.
bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub(crate) struct ModifiersKeys: u8 {
const LSHIFT = 0b0000_0001;
const RSHIFT = 0b0000_0010;
Expand All @@ -1765,51 +1768,3 @@ bitflags! {
const RSUPER = 0b1000_0000;
}
}

#[cfg(feature = "serde")]
mod modifiers_serde {
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use super::ModifiersState;

#[derive(Default, Serialize, Deserialize)]
#[serde(default)]
#[serde(rename = "ModifiersState")]
pub struct ModifiersStateSerialize {
pub shift_key: bool,
pub control_key: bool,
pub alt_key: bool,
pub super_key: bool,
}

impl Serialize for ModifiersState {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = ModifiersStateSerialize {
shift_key: self.shift_key(),
control_key: self.control_key(),
alt_key: self.alt_key(),
super_key: self.super_key(),
};
s.serialize(serializer)
}
}

impl<'de> Deserialize<'de> for ModifiersState {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let ModifiersStateSerialize { shift_key, control_key, alt_key, super_key } =
ModifiersStateSerialize::deserialize(deserializer)?;
let mut m = ModifiersState::empty();
m.set(ModifiersState::SHIFT, shift_key);
m.set(ModifiersState::CONTROL, control_key);
m.set(ModifiersState::ALT, alt_key);
m.set(ModifiersState::SUPER, super_key);
Ok(m)
}
}
}
2 changes: 1 addition & 1 deletion src/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl std::fmt::Display for VideoModeHandle {
/// to check.
///
/// [`Window`]: crate::window::Window
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MonitorHandle {
pub(crate) inner: platform_impl::MonitorHandle,
}
Expand Down
8 changes: 7 additions & 1 deletion src/platform/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
use std::os::raw::c_void;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::monitor::{MonitorHandle, VideoModeHandle};
use crate::window::{Window, WindowAttributes};

Expand Down Expand Up @@ -355,6 +358,7 @@ impl MonitorHandleExtIOS for MonitorHandle {

/// Valid orientations for a particular [`Window`].
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ValidOrientations {
/// Excludes `PortraitUpsideDown` on iphone
#[default]
Expand All @@ -371,6 +375,7 @@ bitflags::bitflags! {
///
/// [edges]: https://developer.apple.com/documentation/uikit/uirectedge?language=objc
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ScreenEdge: u8 {
const NONE = 0;
const TOP = 1 << 0;
Expand All @@ -382,7 +387,8 @@ bitflags::bitflags! {
}
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StatusBarStyle {
#[default]
Default,
Expand Down
3 changes: 2 additions & 1 deletion src/platform/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl WindowExtMacOS for Window {

/// Corresponds to `NSApplicationActivationPolicy`.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ActivationPolicy {
/// Corresponds to `NSApplicationActivationPolicyRegular`.
#[default]
Expand Down Expand Up @@ -432,7 +433,7 @@ impl ActiveEventLoopExtMacOS for &dyn ActiveEventLoop {
/// Option as alt behavior.
///
/// The default is `None`.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum OptionAsAlt {
/// The left `Option` key is treated as `Alt`.
Expand Down
1 change: 1 addition & 0 deletions src/platform/pump_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl EventLoopExtPumpEvents for EventLoop {
}

/// The return status for `pump_events`
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum PumpStatus {
/// Continue running external loop.
Continue,
Expand Down
Loading

0 comments on commit 1168cd4

Please sign in to comment.