summaryrefslogtreecommitdiff
path: root/src/message/history.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/message/history.rs')
-rw-r--r--src/message/history.rs70
1 files changed, 57 insertions, 13 deletions
diff --git a/src/message/history.rs b/src/message/history.rs
index 2abdf2c..92cecc9 100644
--- a/src/message/history.rs
+++ b/src/message/history.rs
@@ -1,18 +1,67 @@
use itertools::Itertools as _;
use super::{
- Message,
+ Body, Id, Message,
event::{Deleted, Event, Sent},
};
-use crate::event::Sequence;
+use crate::{
+ conversation::Conversation,
+ event::{Instant, Sequence},
+ user::{self, User},
+};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
pub message: Message,
}
+// Lifecycle interface
+impl History {
+ pub fn begin(conversation: &Conversation, sender: &User, body: &Body, sent: Instant) -> Self {
+ Self {
+ message: Message {
+ id: Id::generate(),
+ conversation: conversation.id.clone(),
+ sender: sender.id.clone(),
+ body: body.clone(),
+ sent,
+ deleted: None,
+ },
+ }
+ }
+
+ pub fn delete(self, deleted: Instant) -> Result<Self, DeleteError> {
+ if self.message.deleted.is_none() {
+ Ok(Self {
+ message: Message {
+ deleted: Some(deleted),
+ ..self.message
+ },
+ })
+ } else {
+ Err(DeleteError::Deleted(self.into()))
+ }
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum DeleteError {
+ #[error("message {} already deleted", .0.message.id)]
+ // Payload is boxed here to avoid copying an entire `History` around in any errors this error
+ // gets chained into. See <https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err>.
+ Deleted(Box<History>),
+}
+
// State interface
impl History {
+ pub fn id(&self) -> &Id {
+ &self.message.id
+ }
+
+ pub fn sender(&self) -> &user::Id {
+ &self.message.sender
+ }
+
// Snapshot of this message as it was when sent. (Note to the future: it's okay
// if this returns a redacted or modified version of the message. If we
// implement message editing by redacting the original body, then this should
@@ -30,15 +79,16 @@ impl History {
.filter(Sequence::up_to(sequence.into()))
.collect()
}
-
- // Snapshot of this message as of all events recorded in this history.
- pub fn as_snapshot(&self) -> Option<Message> {
- self.events().collect()
- }
}
// Events interface
impl History {
+ pub fn events(&self) -> impl Iterator<Item = Event> + Clone + use<> {
+ [self.sent()]
+ .into_iter()
+ .merge_by(self.deleted(), Sequence::merge)
+ }
+
fn sent(&self) -> Event {
Sent {
message: self.message.clone(),
@@ -55,10 +105,4 @@ impl History {
.into()
})
}
-
- pub fn events(&self) -> impl Iterator<Item = Event> + use<> {
- [self.sent()]
- .into_iter()
- .merge_by(self.deleted(), Sequence::merge)
- }
}