#![allow(dead_code)]
use serde::Serialize;
use utoipa::ToSchema;
#[derive(Serialize, ToSchema)]
pub(crate) struct RoomInfo {
id: i64,
kind: String,
key: Option<String>,
name: Option<String>,
member_count: Option<u32>,
max_members: Option<u32>,
peer: Option<i64>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct RoomInfoPage {
items: Vec<RoomInfo>,
next_cursor: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct ChatMessage {
id: i64,
room: i64,
sender: i64,
sender_name: Option<String>,
text: String,
sent_at: i64,
nonce: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct ChatMessagePage {
items: Vec<ChatMessage>,
next_cursor: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct OpenDirect {
user: i64,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct JoinRoom {
#[schema(value_type = Object)]
room: serde_json::Value,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct LeaveRoom {
room: i64,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct SendMessage {
room: i64,
text: String,
nonce: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct SendAck {
message_id: i64,
sent_at: i64,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct ChatHistory {
room: i64,
cursor: Option<String>,
limit: Option<u32>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct ListMembers {
room: i64,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct RoomMember {
user: i64,
name: Option<String>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct RoomMembers {
room: i64,
members: Vec<RoomMember>,
count: u32,
truncated: Option<bool>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct MessageDeleted {
id: i64,
room: i64,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct Presence {
room: i64,
user: i64,
event: String,
name: Option<String>,
count: Option<u32>,
}
#[derive(Serialize, ToSchema)]
pub(crate) struct Ack {}
#[cfg(test)]
mod tests {
use std::collections::BTreeSet;
use net_backend_protocol::chat as p;
use net_backend_protocol::{Cursor, MessageId, Page, PageRequest, RoomId, UnixMillis, UserId};
use serde_json::Value;
use utoipa::openapi::schema::Schema;
use utoipa::openapi::RefOr;
use utoipa::PartialSchema;
use super::*;
fn properties<T: PartialSchema>() -> BTreeSet<String> {
match T::schema() {
RefOr::T(Schema::Object(object)) => object.properties.keys().cloned().collect(),
_ => BTreeSet::new(),
}
}
fn keys(value: impl serde::Serialize) -> BTreeSet<String> {
match serde_json::to_value(value) {
Ok(Value::Object(map)) => map.keys().cloned().collect(),
_ => BTreeSet::new(),
}
}
#[test]
fn mirrors_match_the_protocol() {
let t = UnixMillis(1);
let room = p::RoomInfo::new(RoomId(1), p::RoomKind::Dm).with_key("k").with_name("n").with_members(Some(1), Some(2)).with_peer(UserId(3));
assert_eq!(properties::<RoomInfo>(), keys(&room));
assert_eq!(properties::<RoomInfoPage>(), keys(Page::new(vec![room], Some(Cursor::new("c")))));
let message = p::ChatMessage::new(MessageId(1), RoomId(1), UserId(1), "x", t).with_sender_name("A").with_nonce("n");
assert_eq!(properties::<ChatMessage>(), keys(&message));
assert_eq!(properties::<ChatMessagePage>(), keys(Page::new(vec![message], Some(Cursor::new("c")))));
assert_eq!(properties::<OpenDirect>(), keys(p::OpenDirect::new(UserId(1))));
assert_eq!(properties::<JoinRoom>(), keys(p::JoinRoom::new("world")));
assert_eq!(properties::<LeaveRoom>(), keys(p::LeaveRoom::new(RoomId(1))));
assert_eq!(properties::<SendMessage>(), keys(p::SendMessage::new(RoomId(1), "x").with_nonce("n")));
assert_eq!(properties::<SendAck>(), keys(p::SendAck::new(MessageId(1), t)));
assert_eq!(properties::<ChatHistory>(), keys(p::ChatHistory::new(RoomId(1)).with_page(PageRequest::after(Cursor::new("c")).with_limit(5))));
assert_eq!(properties::<ListMembers>(), keys(p::ListMembers::new(RoomId(1))));
assert_eq!(properties::<RoomMember>(), keys(p::RoomMember::new(UserId(1)).with_name("A")));
assert_eq!(properties::<RoomMembers>(), keys(p::RoomMembers::new(RoomId(1), vec![], 1).truncated()));
assert_eq!(properties::<MessageDeleted>(), keys(p::MessageDeleted::new(MessageId(1), RoomId(1))));
assert_eq!(properties::<Presence>(), keys(p::Presence::new(RoomId(1), UserId(1), p::PresenceEvent::Joined).with_name("A").with_count(1)));
}
}