use bitflags::bitflags;
use schemars::JsonSchema;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ChannelCapabilities: u32 {
const RICH_TEXT = 1 << 0;
const MEDIA_UPLOAD = 1 << 1;
const THREADS = 1 << 2;
const REACTIONS = 1 << 3;
const TYPING_INDICATOR = 1 << 4;
const EDIT_MESSAGES = 1 << 5;
const DELETE_MESSAGES = 1 << 6;
const VOICE = 1 << 7;
const VIDEO = 1 << 8;
const READ_RECEIPTS = 1 << 9;
const MENTIONS = 1 << 10;
const EMBEDS = 1 << 11;
}
}
impl Serialize for ChannelCapabilities {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.bits().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ChannelCapabilities {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let bits = u32::deserialize(deserializer)?;
ChannelCapabilities::from_bits(bits)
.ok_or_else(|| serde::de::Error::custom(format!("invalid capability bits: {bits}")))
}
}
impl JsonSchema for ChannelCapabilities {
fn schema_name() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed("ChannelCapabilities")
}
fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
u32::json_schema(generator)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn capabilities_combine() {
let caps = ChannelCapabilities::RICH_TEXT | ChannelCapabilities::THREADS;
assert!(caps.contains(ChannelCapabilities::RICH_TEXT));
assert!(caps.contains(ChannelCapabilities::THREADS));
assert!(!caps.contains(ChannelCapabilities::VOICE));
}
#[test]
fn capabilities_serde_roundtrip() {
let caps = ChannelCapabilities::RICH_TEXT
| ChannelCapabilities::MEDIA_UPLOAD
| ChannelCapabilities::REACTIONS;
let json = serde_json::to_string(&caps).unwrap();
let deserialized: ChannelCapabilities = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, caps);
}
}