diff options
Diffstat (limited to 'src/conversation/history.rs')
| -rw-r--r-- | src/conversation/history.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/conversation/history.rs b/src/conversation/history.rs new file mode 100644 index 0000000..601614c --- /dev/null +++ b/src/conversation/history.rs @@ -0,0 +1,69 @@ +use itertools::Itertools as _; + +use super::{ + Conversation, Id, + event::{Created, Deleted, Event}, +}; +use crate::event::{Instant, Sequence}; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct History { + pub conversation: Conversation, + pub deleted: Option<Instant>, +} + +// State interface +impl History { + pub fn id(&self) -> &Id { + &self.conversation.id + } + + // Snapshot of this conversation as it was when created. (Note to the future: + // it's okay if this returns a redacted or modified version of the conversation. + // If we implement renames by redacting the original name, then this should + // return the renamed conversation, not the original, even if that's not how + // it was "as created.") + pub fn as_created(&self) -> Conversation { + self.conversation.clone() + } + + pub fn as_of<S>(&self, sequence: S) -> Option<Conversation> + where + S: Into<Sequence>, + { + self.events() + .filter(Sequence::up_to(sequence.into())) + .collect() + } + + // Snapshot of this conversation as of all events recorded in this history. + pub fn as_snapshot(&self) -> Option<Conversation> { + self.events().collect() + } +} + +// Event factories +impl History { + pub fn events(&self) -> impl Iterator<Item = Event> + use<> { + [self.created()] + .into_iter() + .merge_by(self.deleted(), Sequence::merge) + } + + fn created(&self) -> Event { + Created { + conversation: self.conversation.clone(), + } + .into() + } + + fn deleted(&self) -> Option<Event> { + self.deleted.map(|instant| { + Deleted { + instant, + id: self.conversation.id.clone(), + } + .into() + }) + } +} |
