Skip to main content

arminius_lib_model/
read_receipts.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Data types related to read receipts
6
7use std::collections::BTreeMap;
8
9use arminius_lib_component::error::FeatureNotImplemented;
10use ruma::{
11	OwnedEventId, OwnedRoomId, OwnedUserId,
12	events::receipt::{Receipt, ReceiptType},
13};
14
15/// Type returned when fetching read receipts to sync
16pub type SyncReceiptsMap = BTreeMap<
17	OwnedRoomId,
18	BTreeMap<OwnedEventId, BTreeMap<ReceiptType, BTreeMap<OwnedUserId, Receipt>>>,
19>;
20
21/// Enum representing all the read receipt types stored in the database.
22///
23/// This enum is also defined inside the database. It corresponds to the
24/// different receipt types defined in the Matrix specs (See
25/// <https://spec.matrix.org/latest/client-server-api/#mreceipt_event-receipts>).
26#[derive(Debug, sqlx::Type, PartialEq, Eq, Hash)]
27#[sqlx(type_name = "RECEIPT_TYPE")]
28pub enum DbReceiptType {
29	/// Public read receipt
30	#[sqlx(rename = "m.read")]
31	Read,
32	/// Private read receipt. Only visible by its owning user.
33	#[sqlx(rename = "m.read.private")]
34	ReadPrivate,
35}
36
37/// String representation of our custom read receipt type.
38impl AsRef<str> for DbReceiptType {
39	fn as_ref(&self) -> &str {
40		match self {
41			DbReceiptType::Read => "m.read",
42			DbReceiptType::ReadPrivate => "m.read.private",
43		}
44	}
45}
46
47/// Conversion from ruma's equivalent type: [`ReceiptType`].
48///
49/// Returns a "feature not implemented" error since this can be anything.
50impl TryFrom<ReceiptType> for DbReceiptType {
51	type Error = FeatureNotImplemented;
52
53	fn try_from(receipt_type: ReceiptType) -> Result<Self, Self::Error> {
54		match receipt_type {
55			ReceiptType::Read => Ok(DbReceiptType::Read),
56			ReceiptType::ReadPrivate => Ok(DbReceiptType::ReadPrivate),
57			custom => Err(FeatureNotImplemented(format!(
58				"This server does not support '{custom}' custom read receipts"
59			))),
60		}
61	}
62}
63
64/// Conversion from our database receipt type to ruma's one.
65impl From<DbReceiptType> for ReceiptType {
66	fn from(db_receipt_type: DbReceiptType) -> Self {
67		ReceiptType::from(db_receipt_type.as_ref())
68	}
69}