Skip to main content

tuwunel_api/client/
tag.rs

1use std::collections::BTreeMap;
2
3use axum::extract::State;
4use ruma::{
5	api::client::tag::{create_tag, delete_tag, get_tags},
6	events::{
7		RoomAccountDataEventType,
8		tag::{TagEvent, TagEventContent},
9	},
10};
11use tuwunel_core::Result;
12
13use crate::Ruma;
14
15/// # `PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}`
16///
17/// Adds a tag to the room.
18///
19/// - Inserts the tag into the tag event of the room account data.
20pub(crate) async fn update_tag_route(
21	State(services): State<crate::State>,
22	body: Ruma<create_tag::v3::Request>,
23) -> Result<create_tag::v3::Response> {
24	let sender_user = body.sender_user();
25
26	let mut tags_event = services
27		.account_data
28		.get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag)
29		.await
30		.unwrap_or(TagEvent {
31			content: TagEventContent { tags: BTreeMap::new() },
32		});
33
34	tags_event
35		.content
36		.tags
37		.insert(body.tag.clone().into(), body.tag_info.clone());
38
39	services
40		.account_data
41		.update(
42			Some(&body.room_id),
43			sender_user,
44			RoomAccountDataEventType::Tag,
45			&serde_json::to_value(tags_event)?,
46		)
47		.await?;
48
49	Ok(create_tag::v3::Response {})
50}
51
52/// # `DELETE /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}`
53///
54/// Deletes a tag from the room.
55///
56/// - Removes the tag from the tag event of the room account data.
57pub(crate) async fn delete_tag_route(
58	State(services): State<crate::State>,
59	body: Ruma<delete_tag::v3::Request>,
60) -> Result<delete_tag::v3::Response> {
61	let sender_user = body.sender_user();
62
63	let mut tags_event = services
64		.account_data
65		.get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag)
66		.await
67		.unwrap_or(TagEvent {
68			content: TagEventContent { tags: BTreeMap::new() },
69		});
70
71	tags_event
72		.content
73		.tags
74		.remove(&body.tag.clone().into());
75
76	services
77		.account_data
78		.update(
79			Some(&body.room_id),
80			sender_user,
81			RoomAccountDataEventType::Tag,
82			&serde_json::to_value(tags_event)?,
83		)
84		.await?;
85
86	Ok(delete_tag::v3::Response {})
87}
88
89/// # `GET /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags`
90///
91/// Returns tags on the room.
92///
93/// - Gets the tag event of the room account data.
94pub(crate) async fn get_tags_route(
95	State(services): State<crate::State>,
96	body: Ruma<get_tags::v3::Request>,
97) -> Result<get_tags::v3::Response> {
98	let sender_user = body.sender_user();
99
100	let tags_event = services
101		.account_data
102		.get_room(&body.room_id, sender_user, RoomAccountDataEventType::Tag)
103		.await
104		.unwrap_or(TagEvent {
105			content: TagEventContent { tags: BTreeMap::new() },
106		});
107
108	Ok(get_tags::v3::Response { tags: tags_event.content.tags })
109}