1#[cfg(feature = "unstable-msc4532")]
6use std::borrow::Cow;
7
8#[cfg(feature = "unstable-msc4532")]
9use serde::{Deserialize, Serialize};
10
11#[cfg(feature = "unstable-msc4532")]
12use crate::serde::JsonObject;
13use crate::{PrivOwnedStr, serde::StringEnum};
14
15#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
17#[derive(Clone, Default, StringEnum)]
18#[ruma_enum(rename_all = "snake_case")]
19#[non_exhaustive]
20pub enum PresenceState {
21 Offline,
23
24 #[cfg_attr(not(feature = "unstable-msc4532"), default)]
26 #[cfg_attr(
27 feature = "unstable-msc4532",
28 deprecated(note = "Deprecated when MSC4532 is enabled, use a revised state instead")
29 )]
30 Online,
31
32 #[cfg_attr(
34 feature = "unstable-msc4532",
35 deprecated(note = "Deprecated when MSC4532 is enabled, use a revised state instead")
36 )]
37 Unavailable,
38
39 #[cfg(feature = "unstable-msc4532")]
45 #[default]
46 #[ruma_enum(rename = "org.continuwuity.presence_v2.msc4532.active")]
47 Active,
48
49 #[cfg(feature = "unstable-msc4532")]
55 #[ruma_enum(rename = "org.continuwuity.presence_v2.msc4532.idle")]
56 Idle,
57
58 #[cfg(feature = "unstable-msc4532")]
64 #[ruma_enum(rename = "org.continuwuity.presence_v2.msc4532.busy")]
65 Busy,
66
67 #[doc(hidden)]
68 _Custom(PrivOwnedStr),
69}
70
71#[cfg(feature = "unstable-msc4532")]
72impl PresenceState {
73 #[allow(deprecated)]
80 pub fn as_msc4532_state(&self, currently_active: bool) -> Self {
81 match (self, currently_active) {
82 (Self::Online, true) => Self::Active,
83 (Self::Online, false) => Self::Idle,
84 (Self::Unavailable, _) => Self::Idle,
85 (state, _) => state.clone(),
86 }
87 }
88
89 #[allow(deprecated)]
96 pub fn as_legacy_state(&self) -> Self {
97 match self {
98 Self::Active => Self::Online,
99 Self::Idle => Self::Unavailable,
100 Self::Busy => Self::Unavailable,
101 state => state.clone(),
102 }
103 }
104
105 pub fn is_msc4532_state(&self) -> bool {
111 matches!(self, Self::Active | Self::Idle | Self::Busy | Self::Offline)
112 }
113
114 #[expect(deprecated)]
116 pub fn currently_active(&self) -> bool {
117 matches!(self, Self::Active | Self::Online)
118 }
119}
120
121impl Default for &'_ PresenceState {
122 fn default() -> Self {
123 #[cfg(feature = "unstable-msc4532")]
124 {
125 &PresenceState::Active
126 }
127 #[cfg(not(feature = "unstable-msc4532"))]
128 {
129 &PresenceState::Online
130 }
131 }
132}
133
134#[cfg(feature = "unstable-msc4532")]
136#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
137#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
138pub struct PresenceStatus {
139 #[serde(skip_serializing_if = "Option::is_none")]
141 pub msg: Option<String>,
142
143 #[serde(flatten)]
145 data: JsonObject,
146}
147
148#[cfg(feature = "unstable-msc4532")]
149impl PresenceStatus {
150 pub fn new(msg: Option<String>) -> Self {
152 Self { msg, data: JsonObject::new() }
153 }
154
155 pub fn with_data(msg: Option<String>, mut data: JsonObject) -> Self {
157 data.remove("msg");
158 Self { msg, data }
159 }
160
161 pub fn data(&self) -> Cow<'_, JsonObject> {
168 Cow::Borrowed(&self.data)
169 }
170}