diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-10-09 11:45:46 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-10-09 11:45:46 -0400 |
| commit | fecc78192ff1ad83c6a2f41e35a65ac189d25c6f (patch) | |
| tree | 481d82e99cf8aad8fe256d8186ae72bcee23bf9f /src/message | |
| parent | dd62b823e01934a0f841256fdb17b551091896bf (diff) | |
| parent | 2f0b77e8fd02a137047c8975a573626cd76310ff (diff) | |
Merge branch 'wip/event-vocabulary'
Diffstat (limited to 'src/message')
| -rw-r--r-- | src/message/app.rs | 2 | ||||
| -rw-r--r-- | src/message/event.rs | 30 | ||||
| -rw-r--r-- | src/message/history.rs | 17 | ||||
| -rw-r--r-- | src/message/repo.rs | 125 | ||||
| -rw-r--r-- | src/message/snapshot.rs | 49 |
5 files changed, 90 insertions, 133 deletions
diff --git a/src/message/app.rs b/src/message/app.rs index 385c92e..3385af2 100644 --- a/src/message/app.rs +++ b/src/message/app.rs @@ -7,7 +7,7 @@ use crate::{ channel::{self, repo::Provider as _}, clock::DateTime, db::NotFound as _, - event::{broadcaster::Broadcaster, repo::Provider as _, Event, Sequence}, + event::{repo::Provider as _, Broadcaster, Event, Sequence}, login::Login, }; diff --git a/src/message/event.rs b/src/message/event.rs index 66db9b0..1cd5847 100644 --- a/src/message/event.rs +++ b/src/message/event.rs @@ -1,29 +1,14 @@ use super::{snapshot::Message, Id}; -use crate::{ - channel::Channel, - event::{Instant, Sequenced}, -}; +use crate::event::{Instant, Sequenced}; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -pub struct Event { - #[serde(flatten)] - pub kind: Kind, -} - -impl Sequenced for Event { - fn instant(&self) -> Instant { - self.kind.instant() - } -} - -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum Kind { +#[serde(tag = "event", rename_all = "snake_case")] +pub enum Event { Sent(Sent), Deleted(Deleted), } -impl Sequenced for Kind { +impl Sequenced for Event { fn instant(&self) -> Instant { match self { Self::Sent(sent) => sent.instant(), @@ -44,7 +29,7 @@ impl Sequenced for Sent { } } -impl From<Sent> for Kind { +impl From<Sent> for Event { fn from(event: Sent) -> Self { Self::Sent(event) } @@ -54,8 +39,7 @@ impl From<Sent> for Kind { pub struct Deleted { #[serde(flatten)] pub instant: Instant, - pub channel: Channel, - pub message: Id, + pub id: Id, } impl Sequenced for Deleted { @@ -64,7 +48,7 @@ impl Sequenced for Deleted { } } -impl From<Deleted> for Kind { +impl From<Deleted> for Event { fn from(event: Deleted) -> Self { Self::Deleted(event) } diff --git a/src/message/history.rs b/src/message/history.rs index f267f4c..09e69b7 100644 --- a/src/message/history.rs +++ b/src/message/history.rs @@ -35,22 +35,19 @@ impl History { // Events interface impl History { fn sent(&self) -> Event { - Event { - kind: Sent { - message: self.message.clone(), - } - .into(), + Sent { + message: self.message.clone(), } + .into() } fn deleted(&self) -> Option<Event> { - self.deleted.map(|instant| Event { - kind: Deleted { + self.deleted.map(|instant| { + Deleted { instant, - channel: self.message.channel.clone(), - message: self.message.id.clone(), + id: self.message.id.clone(), } - .into(), + .into() }) } diff --git a/src/message/repo.rs b/src/message/repo.rs index 5b199a7..71c6d10 100644 --- a/src/message/repo.rs +++ b/src/message/repo.rs @@ -2,7 +2,7 @@ use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; use super::{snapshot::Message, History, Id}; use crate::{ - channel::{self, Channel}, + channel, clock::DateTime, event::{Instant, ResumePoint, Sequence}, login::{self, Login}, @@ -38,6 +38,10 @@ impl<'c> Messages<'c> { values ($1, $2, $3, $4, $5, $6) returning id as "id: Id", + channel as "channel: channel::Id", + sender as "sender: login::Id", + sent_at as "sent_at: DateTime", + sent_sequence as "sent_sequence: Sequence", body "#, id, @@ -49,12 +53,12 @@ impl<'c> Messages<'c> { ) .map(|row| History { message: Message { - sent: *sent, - // Use "as created" here as we don't care about providing a perfectly up-to-date - // representation of the channel. The `name` is informational (and the ID, which is - // normative, is fixed over time). - channel: channel.as_created(), - sender: sender.clone(), + sent: Instant { + at: row.sent_at, + sequence: row.sent_sequence, + }, + channel: row.channel, + sender: row.sender, id: row.id, body: row.body, }, @@ -75,20 +79,16 @@ impl<'c> Messages<'c> { let messages = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", - sender.id as "sender_id: login::Id", - sender.name as "sender_name", - message.id as "id: Id", - message.body, + channel as "channel: channel::Id", + sender as "sender: login::Id", + id as "id: Id", + body, sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id - join login as sender on message.sender = sender.id - where channel.id = $1 - and coalesce(message.sent_sequence <= $2, true) - order by message.sent_sequence + where channel = $1 + and coalesce(sent_sequence <= $2, true) + order by sent_sequence "#, channel_id, resume_at, @@ -99,14 +99,43 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, - sender: Login { - id: row.sender_id, - name: row.sender_name, + channel: row.channel, + sender: row.sender, + id: row.id, + body: row.body, + }, + deleted: None, + }) + .fetch_all(&mut *self.0) + .await?; + + Ok(messages) + } + + pub async fn all(&mut self, resume_at: ResumePoint) -> Result<Vec<History>, sqlx::Error> { + let messages = sqlx::query!( + r#" + select + channel as "channel: channel::Id", + sender as "sender: login::Id", + id as "id: Id", + body, + sent_at as "sent_at: DateTime", + sent_sequence as "sent_sequence: Sequence" + from message + where coalesce(sent_sequence <= $2, true) + order by sent_sequence + "#, + resume_at, + ) + .map(|row| History { + message: Message { + sent: Instant { + at: row.sent_at, + sequence: row.sent_sequence, }, + channel: row.channel, + sender: row.sender, id: row.id, body: row.body, }, @@ -122,18 +151,14 @@ impl<'c> Messages<'c> { let message = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", - sender.id as "sender_id: login::Id", - sender.name as "sender_name", - message.id as "id: Id", - message.body, + channel as "channel: channel::Id", + sender as "sender: login::Id", + id as "id: Id", + body, sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id - join login as sender on message.sender = sender.id - where message.id = $1 + where id = $1 "#, message, ) @@ -143,14 +168,8 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, - sender: Login { - id: row.sender_id, - name: row.sender_name, - }, + channel: row.channel, + sender: row.sender, id: row.id, body: row.body, }, @@ -207,17 +226,13 @@ impl<'c> Messages<'c> { let messages = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", - sender.id as "sender_id: login::Id", - sender.name as "sender_name", - message.id as "id: Id", - message.body, + channel as "channel: channel::Id", + sender as "sender: login::Id", + id as "id: Id", + body, sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id - join login as sender on message.sender = sender.id where coalesce(message.sent_sequence > $1, true) "#, resume_at, @@ -228,14 +243,8 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, - sender: Login { - id: row.sender_id, - name: row.sender_name, - }, + channel: row.channel, + sender: row.sender, id: row.id, body: row.body, }, diff --git a/src/message/snapshot.rs b/src/message/snapshot.rs index 522c1aa..0eb37bb 100644 --- a/src/message/snapshot.rs +++ b/src/message/snapshot.rs @@ -1,57 +1,24 @@ use super::{ - event::{Event, Kind, Sent}, + event::{Event, Sent}, Id, }; -use crate::{channel::Channel, event::Instant, login::Login}; +use crate::{channel, event::Instant, login}; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -#[serde(into = "self::serialize::Message")] pub struct Message { - #[serde(skip)] + #[serde(flatten)] pub sent: Instant, - pub channel: Channel, - pub sender: Login, + pub channel: channel::Id, + pub sender: login::Id, pub id: Id, pub body: String, } -mod serialize { - use crate::{channel::Channel, login::Login, message::Id}; - - #[derive(serde::Serialize)] - pub struct Message { - channel: Channel, - sender: Login, - #[allow(clippy::struct_field_names)] - // Deliberately redundant with the module path; this produces a specific serialization. - message: MessageData, - } - - #[derive(serde::Serialize)] - pub struct MessageData { - id: Id, - body: String, - } - - impl From<super::Message> for Message { - fn from(message: super::Message) -> Self { - Self { - channel: message.channel, - sender: message.sender, - message: MessageData { - id: message.id, - body: message.body, - }, - } - } - } -} - impl Message { fn apply(state: Option<Self>, event: Event) -> Option<Self> { - match (state, event.kind) { - (None, Kind::Sent(event)) => Some(event.into()), - (Some(message), Kind::Deleted(event)) if message.id == event.message => None, + match (state, event) { + (None, Event::Sent(event)) => Some(event.into()), + (Some(message), Event::Deleted(event)) if message.id == event.id => None, (state, event) => panic!("invalid message event {event:#?} for state {state:#?}"), } } |
