ruma_common/
to_device.rs

1//! Common types for the Send-To-Device Messaging
2//!
3//! [send-to-device]: https://spec.matrix.org/latest/client-server-api/#send-to-device-messaging
4
5use std::fmt::{Display, Formatter, Result as FmtResult};
6
7use serde::{
8    de::{self, Unexpected},
9    Deserialize, Deserializer, Serialize, Serializer,
10};
11
12use crate::OwnedDeviceId;
13
14/// Represents one or all of a user's devices.
15#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16#[allow(clippy::exhaustive_enums)]
17pub enum DeviceIdOrAllDevices {
18    /// Represents a device Id for one of a user's devices.
19    DeviceId(OwnedDeviceId),
20
21    /// Represents all devices for a user.
22    AllDevices,
23}
24
25impl Display for DeviceIdOrAllDevices {
26    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
27        match self {
28            DeviceIdOrAllDevices::DeviceId(device_id) => write!(f, "{device_id}"),
29            DeviceIdOrAllDevices::AllDevices => write!(f, "*"),
30        }
31    }
32}
33
34impl From<OwnedDeviceId> for DeviceIdOrAllDevices {
35    fn from(d: OwnedDeviceId) -> Self {
36        DeviceIdOrAllDevices::DeviceId(d)
37    }
38}
39
40impl TryFrom<&str> for DeviceIdOrAllDevices {
41    type Error = &'static str;
42
43    fn try_from(device_id_or_all_devices: &str) -> Result<Self, Self::Error> {
44        if device_id_or_all_devices.is_empty() {
45            Err("Device identifier cannot be empty")
46        } else if "*" == device_id_or_all_devices {
47            Ok(DeviceIdOrAllDevices::AllDevices)
48        } else {
49            Ok(DeviceIdOrAllDevices::DeviceId(device_id_or_all_devices.into()))
50        }
51    }
52}
53
54impl Serialize for DeviceIdOrAllDevices {
55    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
56    where
57        S: Serializer,
58    {
59        match self {
60            Self::DeviceId(device_id) => device_id.serialize(serializer),
61            Self::AllDevices => serializer.serialize_str("*"),
62        }
63    }
64}
65
66impl<'de> Deserialize<'de> for DeviceIdOrAllDevices {
67    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68    where
69        D: Deserializer<'de>,
70    {
71        let s = crate::serde::deserialize_cow_str(deserializer)?;
72        DeviceIdOrAllDevices::try_from(s.as_ref()).map_err(|_| {
73            de::Error::invalid_value(Unexpected::Str(&s), &"a valid device identifier or '*'")
74        })
75    }
76}