use reqwest::Url;
use salvo::prelude::*;
use serde::{Deserialize, Serialize};
use crate::events::space::child::HierarchySpaceChildEvent;
use crate::sending::{SendRequest, SendResult};
use crate::{OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, room::RoomType, serde::RawJson, space::SpaceRoomJoinRule};
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct SpaceHierarchyParentSummary {
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::serde::empty_string_as_none"
)]
pub canonical_alias: Option<OwnedRoomAliasId>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub num_joined_members: u64,
pub room_id: OwnedRoomId,
#[serde(skip_serializing_if = "Option::is_none")]
pub topic: Option<String>,
pub world_readable: bool,
pub guest_can_join: bool,
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::serde::empty_string_as_none"
)]
pub avatar_url: Option<OwnedMxcUri>,
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
pub join_rule: SpaceRoomJoinRule,
#[serde(skip_serializing_if = "Option::is_none")]
pub room_type: Option<RoomType>,
pub children_state: Vec<RawJson<HierarchySpaceChildEvent>>,
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
pub allowed_room_ids: Vec<OwnedRoomId>,
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct SpaceHierarchyChildSummary {
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::serde::empty_string_as_none"
)]
pub canonical_alias: Option<OwnedRoomAliasId>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub num_joined_members: u64,
pub room_id: OwnedRoomId,
#[serde(skip_serializing_if = "Option::is_none")]
pub topic: Option<String>,
pub world_readable: bool,
pub guest_can_join: bool,
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::serde::empty_string_as_none"
)]
pub avatar_url: Option<OwnedMxcUri>,
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
pub join_rule: SpaceRoomJoinRule,
#[serde(skip_serializing_if = "Option::is_none")]
pub room_type: Option<RoomType>,
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
pub allowed_room_ids: Vec<OwnedRoomId>,
}
impl From<SpaceHierarchyParentSummary> for SpaceHierarchyChildSummary {
fn from(parent: SpaceHierarchyParentSummary) -> Self {
let SpaceHierarchyParentSummary {
canonical_alias,
name,
num_joined_members,
room_id,
topic,
world_readable,
guest_can_join,
avatar_url,
join_rule,
room_type,
children_state: _,
allowed_room_ids,
} = parent;
Self {
canonical_alias,
name,
num_joined_members,
room_id,
topic,
world_readable,
guest_can_join,
avatar_url,
join_rule,
room_type,
allowed_room_ids,
}
}
}
pub fn hierarchy_request(origin: &str, args: HierarchyReqArgs) -> SendResult<SendRequest> {
let url = Url::parse(&format!(
"{origin}/_matrix/client/v1/rooms/{}/hierarchy?suggested_only={}",
args.room_id, args.suggested_only
))?;
Ok(crate::sending::get(url))
}
#[derive(ToParameters, Deserialize, Debug)]
pub struct HierarchyReqArgs {
#[salvo(parameter(parameter_in = Path))]
pub room_id: OwnedRoomId,
#[salvo(parameter(parameter_in = Query))]
#[serde(default, skip_serializing_if = "crate::serde::is_default")]
pub suggested_only: bool,
}
#[derive(ToSchema, Serialize, Deserialize, Debug)]
pub struct HierarchyResBody {
pub children: Vec<SpaceHierarchyChildSummary>,
pub inaccessible_children: Vec<OwnedRoomId>,
pub room: SpaceHierarchyParentSummary,
}
impl HierarchyResBody {
pub fn new(room_summary: SpaceHierarchyParentSummary) -> Self {
Self {
children: Vec::new(),
inaccessible_children: Vec::new(),
room: room_summary,
}
}
}