ruma_events/
voice.rs

1//! Types for voice message events ([MSC3245]).
2//!
3//! [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/pull/3245
4
5use std::time::Duration;
6
7use ruma_macros::EventContent;
8use serde::{Deserialize, Serialize};
9
10use super::{
11    audio::Amplitude, file::FileContentBlock, message::TextContentBlock, room::message::Relation,
12};
13
14/// The payload for an extensible voice message.
15///
16/// This is the new primary type introduced in [MSC3245] and can be sent in rooms with a version
17/// that doesn't support extensible events. See the documentation of the [`message`] module for more
18/// information.
19///
20/// [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/pull/3245
21/// [`message`]: super::message
22#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
23#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
24#[ruma_event(type = "org.matrix.msc3245.voice.v2", kind = MessageLike, without_relation)]
25pub struct VoiceEventContent {
26    /// The text representation of the message.
27    #[serde(rename = "org.matrix.msc1767.text")]
28    pub text: TextContentBlock,
29
30    /// The file content of the message.
31    #[serde(rename = "org.matrix.msc1767.file")]
32    pub file: FileContentBlock,
33
34    /// The audio content of the message.
35    #[serde(rename = "org.matrix.msc1767.audio_details")]
36    pub audio_details: VoiceAudioDetailsContentBlock,
37
38    /// Whether this message is automated.
39    #[cfg(feature = "unstable-msc3955")]
40    #[serde(
41        default,
42        skip_serializing_if = "ruma_common::serde::is_default",
43        rename = "org.matrix.msc1767.automated"
44    )]
45    pub automated: bool,
46
47    /// Information about related messages.
48    #[serde(
49        flatten,
50        skip_serializing_if = "Option::is_none",
51        deserialize_with = "crate::room::message::relation_serde::deserialize_relation"
52    )]
53    pub relates_to: Option<Relation<VoiceEventContentWithoutRelation>>,
54}
55
56impl VoiceEventContent {
57    /// Creates a new `VoiceEventContent` with the given fallback representation, file and audio
58    /// details.
59    pub fn new(
60        text: TextContentBlock,
61        file: FileContentBlock,
62        audio_details: VoiceAudioDetailsContentBlock,
63    ) -> Self {
64        Self {
65            text,
66            file,
67            audio_details,
68            #[cfg(feature = "unstable-msc3955")]
69            automated: false,
70            relates_to: None,
71        }
72    }
73
74    /// Creates a new `VoiceEventContent` with the given plain text fallback representation, file
75    /// and audio details.
76    pub fn with_plain_text(
77        plain_text: impl Into<String>,
78        file: FileContentBlock,
79        audio_details: VoiceAudioDetailsContentBlock,
80    ) -> Self {
81        Self {
82            text: TextContentBlock::plain(plain_text),
83            file,
84            audio_details,
85            #[cfg(feature = "unstable-msc3955")]
86            automated: false,
87            relates_to: None,
88        }
89    }
90}
91
92/// A block for details of voice audio content.
93#[derive(Clone, Debug, Serialize, Deserialize)]
94#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
95pub struct VoiceAudioDetailsContentBlock {
96    /// The duration of the audio in seconds.
97    #[serde(with = "ruma_common::serde::duration::secs")]
98    pub duration: Duration,
99
100    /// The waveform representation of the content.
101    #[serde(rename = "org.matrix.msc3246.waveform")]
102    pub waveform: Vec<Amplitude>,
103}
104
105impl VoiceAudioDetailsContentBlock {
106    /// Creates a new `AudioDetailsContentBlock` with the given duration and waveform
107    /// representation.
108    pub fn new(duration: Duration, waveform: Vec<Amplitude>) -> Self {
109        Self { duration, waveform }
110    }
111}