ruma_common/
to_device.rs
1use 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#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16#[allow(clippy::exhaustive_enums)]
17pub enum DeviceIdOrAllDevices {
18 DeviceId(OwnedDeviceId),
20
21 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}