use itertools::Itertools;
use reqwest::Url;
use salvo::prelude::*;
use serde::{Deserialize, Serialize};
use crate::events::AnyStrippedStateEvent;
use crate::sending::{SendRequest, SendResult};
use crate::serde::{RawJson, RawJsonValue};
use crate::{OwnedEventId, OwnedRoomId, OwnedUserId, RoomVersionId};
pub fn make_knock_request(origin: &str, args: MakeKnockReqArgs) -> SendResult<SendRequest> {
let ver = args.ver.iter().map(|v| format!("ver={v}")).join("&");
let ver = if ver.is_empty() { "" } else { &*format!("?{}", ver) };
let url = Url::parse(&format!(
"{origin}/_matrix/federation/v1/make_knock/{}/{}{}",
args.room_id, args.user_id, ver
))?;
Ok(crate::sending::get(url))
}
#[derive(ToParameters, Deserialize, Debug)]
pub struct MakeKnockReqArgs {
#[salvo(parameter(parameter_in = Path))]
pub room_id: OwnedRoomId,
#[salvo(parameter(parameter_in = Path))]
pub user_id: OwnedUserId,
#[salvo(parameter(parameter_in = Query))]
pub ver: Vec<RoomVersionId>,
}
#[derive(ToSchema, Serialize, Deserialize, Debug)]
pub struct MakeKnockResBody {
pub room_version: RoomVersionId,
#[salvo(schema(value_type = Object, additional_properties = true))]
pub event: Box<RawJsonValue>,
}
impl MakeKnockResBody {
pub fn new(room_version: RoomVersionId, event: Box<RawJsonValue>) -> Self {
Self { room_version, event }
}
}
pub fn send_knock_request(origin: &str, args: SendKnockReqArgs, body: SendKnockReqBody) -> SendResult<SendRequest> {
let url = Url::parse(&format!(
"{origin}/_matrix/federation/v1/send_knock/{}/{}",
args.room_id, args.event_id
))?;
Ok(crate::sending::put(url).stuff(body)?)
}
#[derive(ToParameters, Deserialize, Debug)]
pub struct SendKnockReqArgs {
#[salvo(parameter(parameter_in = Path))]
pub room_id: OwnedRoomId,
#[salvo(parameter(parameter_in = Path))]
pub event_id: OwnedEventId,
}
#[derive(ToSchema, Serialize, Deserialize, Debug)]
pub struct SendKnockReqBody {
#[salvo(schema(value_type = Object, additional_properties = true))]
#[serde(flatten)]
pub pdu: Box<RawJsonValue>,
}
impl SendKnockReqBody {
pub fn new(pdu: Box<RawJsonValue>) -> Self {
Self { pdu }
}
}
crate::json_body_modifier!(SendKnockReqBody);
#[derive(ToSchema, Serialize, Deserialize, Debug)]
pub struct SendKnockResBody {
pub knock_room_state: Vec<RawJson<AnyStrippedStateEvent>>,
}
impl SendKnockResBody {
pub fn new(knock_room_state: Vec<RawJson<AnyStrippedStateEvent>>) -> Self {
Self { knock_room_state }
}
}