summaryrefslogtreecommitdiff
path: root/src/conversation/history.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-08-26 02:25:57 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-08-26 18:05:00 -0400
commitca4ac1d0f12532c38d4041aba6ae50ae4093ae13 (patch)
tree60b155ae0445e162b6b9d1c7763b88d4eaa1571a /src/conversation/history.rs
parenta54c548bf00f881f36d2adc3a6a2614b5f72f9ce (diff)
Store `Conversation` instances using their events.
This replaces the approach of having the repo type know about conversation lifecycle in detail. Instead, the repo type accepts events and applies them to the DB blindly. The SQL written to implement each event does, however, embed assumptions about what order events will happen in.
Diffstat (limited to 'src/conversation/history.rs')
-rw-r--r--src/conversation/history.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/conversation/history.rs b/src/conversation/history.rs
index 8821277..5cba9ca 100644
--- a/src/conversation/history.rs
+++ b/src/conversation/history.rs
@@ -4,13 +4,49 @@ use super::{
Conversation, Id,
event::{Created, Deleted, Event},
};
-use crate::event::Sequence;
+use crate::{
+ event::{Instant, Sequence},
+ name::Name,
+};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
pub conversation: Conversation,
}
+// Lifecycle interface
+impl History {
+ pub fn begin(name: &Name, created: Instant) -> Self {
+ Self {
+ conversation: Conversation {
+ id: Id::generate(),
+ name: name.clone(),
+ created,
+ deleted: None,
+ },
+ }
+ }
+
+ pub fn delete(self, deleted: Instant) -> Result<Self, DeleteError> {
+ if self.conversation.deleted.is_none() {
+ Ok(Self {
+ conversation: Conversation {
+ deleted: Some(deleted),
+ ..self.conversation
+ },
+ })
+ } else {
+ Err(DeleteError::Deleted(self))
+ }
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum DeleteError {
+ #[error("conversation {} already deleted", .0.conversation.id)]
+ Deleted(History),
+}
+
// State interface
impl History {
pub fn id(&self) -> &Id {
@@ -41,7 +77,7 @@ impl History {
// Event factories
impl History {
- pub fn events(&self) -> impl Iterator<Item = Event> + use<> {
+ pub fn events(&self) -> impl Iterator<Item = Event> + Clone + use<> {
[self.created()]
.into_iter()
.merge_by(self.deleted(), Sequence::merge)