summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/channel/app.rs13
-rw-r--r--src/channel/history.rs31
-rw-r--r--src/message/app.rs7
-rw-r--r--src/message/history.rs23
-rw-r--r--src/message/repo.rs15
5 files changed, 57 insertions, 32 deletions
diff --git a/src/channel/app.rs b/src/channel/app.rs
index bb331ec..1b2cc48 100644
--- a/src/channel/app.rs
+++ b/src/channel/app.rs
@@ -33,7 +33,7 @@ impl<'a> Channels<'a> {
self.events
.broadcast(channel.events().map(Event::from).collect::<Vec<_>>());
- Ok(channel.snapshot())
+ Ok(channel.as_created())
}
pub async fn all(&self, resume_point: Option<Sequence>) -> Result<Vec<Channel>, InternalError> {
@@ -64,8 +64,7 @@ impl<'a> Channels<'a> {
.channels()
.by_id(channel)
.await
- .not_found(|| Error::NotFound(channel.clone()))?
- .snapshot();
+ .not_found(|| Error::NotFound(channel.clone()))?;
let messages = tx
.messages()
@@ -90,16 +89,14 @@ impl<'a> Channels<'a> {
.channels()
.by_id(channel)
.await
- .not_found(|| Error::NotFound(channel.clone()))?
- .snapshot();
+ .not_found(|| Error::NotFound(channel.clone()))?;
let mut events = Vec::new();
let messages = tx.messages().in_channel(&channel, None).await?;
for message in messages {
- let message = message.snapshot();
let deleted = tx.sequence().next(deleted_at).await?;
- let message = tx.messages().delete(&message.id, &deleted).await?;
+ let message = tx.messages().delete(message.id(), &deleted).await?;
events.extend(
message
.events()
@@ -109,7 +106,7 @@ impl<'a> Channels<'a> {
}
let deleted = tx.sequence().next(deleted_at).await?;
- let channel = tx.channels().delete(&channel.id, &deleted).await?;
+ let channel = tx.channels().delete(channel.id(), &deleted).await?;
events.extend(
channel
.events()
diff --git a/src/channel/history.rs b/src/channel/history.rs
index 3cc7d9d..bd45d8d 100644
--- a/src/channel/history.rs
+++ b/src/channel/history.rs
@@ -1,6 +1,6 @@
use super::{
event::{Created, Deleted, Event},
- Channel,
+ Channel, Id,
};
use crate::event::Instant;
@@ -11,7 +11,28 @@ pub struct History {
pub deleted: Option<Instant>,
}
+// State interface
impl History {
+ pub fn id(&self) -> &Id {
+ &self.channel.id
+ }
+
+ // Snapshot of this channel as it was when created. (Note to the future: it's
+ // okay if this returns a redacted or modified version of the channel. If we
+ // implement renames by redacting the original name, then this should return the
+ // renamed channel, not the original, even if that's not how it was "as
+ // created.")
+ pub fn as_created(&self) -> Channel {
+ self.channel.clone()
+ }
+}
+
+// Event factories
+impl History {
+ pub fn events(&self) -> impl Iterator<Item = Event> {
+ [self.created()].into_iter().chain(self.deleted())
+ }
+
fn created(&self) -> Event {
Event {
instant: self.created,
@@ -31,12 +52,4 @@ impl History {
.into(),
})
}
-
- pub fn events(&self) -> impl Iterator<Item = Event> {
- [self.created()].into_iter().chain(self.deleted())
- }
-
- pub fn snapshot(&self) -> Channel {
- self.channel.clone()
- }
}
diff --git a/src/message/app.rs b/src/message/app.rs
index 33ea8ad..385c92e 100644
--- a/src/message/app.rs
+++ b/src/message/app.rs
@@ -35,16 +35,13 @@ impl<'a> Messages<'a> {
.await
.not_found(|| SendError::ChannelNotFound(channel.clone()))?;
let sent = tx.sequence().next(sent_at).await?;
- let message = tx
- .messages()
- .create(&channel.snapshot(), sender, &sent, body)
- .await?;
+ let message = tx.messages().create(&channel, sender, &sent, body).await?;
tx.commit().await?;
self.events
.broadcast(message.events().map(Event::from).collect::<Vec<_>>());
- Ok(message.snapshot())
+ Ok(message.as_sent())
}
pub async fn delete(&self, message: &Id, deleted_at: &DateTime) -> Result<(), DeleteError> {
diff --git a/src/message/history.rs b/src/message/history.rs
index 89fc6b1..c44d954 100644
--- a/src/message/history.rs
+++ b/src/message/history.rs
@@ -1,6 +1,6 @@
use super::{
event::{Deleted, Event, Sent},
- Message,
+ Id, Message,
};
use crate::event::Instant;
@@ -10,6 +10,23 @@ pub struct History {
pub deleted: Option<Instant>,
}
+// State interface
+impl History {
+ pub fn id(&self) -> &Id {
+ &self.message.id
+ }
+
+ // 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
+ // return the edited message, not the original, even if that's not how it was
+ // "as sent.")
+ pub fn as_sent(&self) -> Message {
+ self.message.clone()
+ }
+}
+
+// Events interface
impl History {
fn sent(&self) -> Event {
Event {
@@ -34,8 +51,4 @@ impl History {
pub fn events(&self) -> impl Iterator<Item = Event> {
[self.sent()].into_iter().chain(self.deleted())
}
-
- pub fn snapshot(&self) -> Message {
- self.message.clone()
- }
}
diff --git a/src/message/repo.rs b/src/message/repo.rs
index fc835c8..2ca409d 100644
--- a/src/message/repo.rs
+++ b/src/message/repo.rs
@@ -23,12 +23,13 @@ pub struct Messages<'t>(&'t mut SqliteConnection);
impl<'c> Messages<'c> {
pub async fn create(
&mut self,
- channel: &Channel,
+ channel: &channel::History,
sender: &Login,
sent: &Instant,
body: &str,
) -> Result<History, sqlx::Error> {
let id = Id::generate();
+ let channel_id = channel.id();
let message = sqlx::query!(
r#"
@@ -40,7 +41,7 @@ impl<'c> Messages<'c> {
body
"#,
id,
- channel.id,
+ channel_id,
sender.id,
sent.at,
sent.sequence,
@@ -49,7 +50,10 @@ impl<'c> Messages<'c> {
.map(|row| History {
message: Message {
sent: *sent,
- channel: channel.clone(),
+ // 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(),
id: row.id,
body: row.body,
@@ -64,9 +68,10 @@ impl<'c> Messages<'c> {
pub async fn in_channel(
&mut self,
- channel: &Channel,
+ channel: &channel::History,
resume_at: Option<Sequence>,
) -> Result<Vec<History>, sqlx::Error> {
+ let channel_id = channel.id();
let messages = sqlx::query!(
r#"
select
@@ -85,7 +90,7 @@ impl<'c> Messages<'c> {
and coalesce(message.sent_sequence <= $2, true)
order by message.sent_sequence
"#,
- channel.id,
+ channel_id,
resume_at,
)
.map(|row| History {