summaryrefslogtreecommitdiff
path: root/src/channel
diff options
context:
space:
mode:
Diffstat (limited to 'src/channel')
-rw-r--r--src/channel/app.rs48
-rw-r--r--src/channel/history.rs8
-rw-r--r--src/channel/repo.rs4
-rw-r--r--src/channel/routes.rs89
-rw-r--r--src/channel/routes/test/list.rs65
-rw-r--r--src/channel/routes/test/mod.rs1
-rw-r--r--src/channel/routes/test/on_create.rs7
7 files changed, 17 insertions, 205 deletions
diff --git a/src/channel/app.rs b/src/channel/app.rs
index 1b2cc48..a9a9e84 100644
--- a/src/channel/app.rs
+++ b/src/channel/app.rs
@@ -7,7 +7,7 @@ use crate::{
clock::DateTime,
db::NotFound,
event::{broadcaster::Broadcaster, repo::Provider as _, Event, Sequence},
- message::{repo::Provider as _, Message},
+ message::repo::Provider as _,
};
pub struct Channels<'a> {
@@ -36,52 +36,6 @@ impl<'a> Channels<'a> {
Ok(channel.as_created())
}
- pub async fn all(&self, resume_point: Option<Sequence>) -> Result<Vec<Channel>, InternalError> {
- let mut tx = self.db.begin().await?;
- let channels = tx.channels().all(resume_point).await?;
- tx.commit().await?;
-
- let channels = channels
- .into_iter()
- .filter_map(|channel| {
- channel
- .events()
- .filter(Sequence::up_to(resume_point))
- .collect()
- })
- .collect();
-
- Ok(channels)
- }
-
- pub async fn messages(
- &self,
- channel: &Id,
- resume_point: Option<Sequence>,
- ) -> Result<Vec<Message>, Error> {
- let mut tx = self.db.begin().await?;
- let channel = tx
- .channels()
- .by_id(channel)
- .await
- .not_found(|| Error::NotFound(channel.clone()))?;
-
- let messages = tx
- .messages()
- .in_channel(&channel, resume_point)
- .await?
- .into_iter()
- .filter_map(|message| {
- message
- .events()
- .filter(Sequence::up_to(resume_point))
- .collect()
- })
- .collect();
-
- Ok(messages)
- }
-
pub async fn delete(&self, channel: &Id, deleted_at: &DateTime) -> Result<(), Error> {
let mut tx = self.db.begin().await?;
diff --git a/src/channel/history.rs b/src/channel/history.rs
index bd45d8d..383fb7b 100644
--- a/src/channel/history.rs
+++ b/src/channel/history.rs
@@ -2,7 +2,7 @@ use super::{
event::{Created, Deleted, Event},
Channel, Id,
};
-use crate::event::Instant;
+use crate::event::{Instant, ResumePoint, Sequence};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
@@ -25,6 +25,12 @@ impl History {
pub fn as_created(&self) -> Channel {
self.channel.clone()
}
+
+ pub fn as_of(&self, resume_point: impl Into<ResumePoint>) -> Option<Channel> {
+ self.events()
+ .filter(Sequence::up_to(resume_point.into()))
+ .collect()
+ }
}
// Event factories
diff --git a/src/channel/repo.rs b/src/channel/repo.rs
index 2b48436..2f57581 100644
--- a/src/channel/repo.rs
+++ b/src/channel/repo.rs
@@ -3,7 +3,7 @@ use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction};
use crate::{
channel::{Channel, History, Id},
clock::DateTime,
- event::{Instant, Sequence},
+ event::{Instant, ResumePoint, Sequence},
};
pub trait Provider {
@@ -84,7 +84,7 @@ impl<'c> Channels<'c> {
Ok(channel)
}
- pub async fn all(&mut self, resume_at: Option<Sequence>) -> Result<Vec<History>, sqlx::Error> {
+ pub async fn all(&mut self, resume_at: ResumePoint) -> Result<Vec<History>, sqlx::Error> {
let channels = sqlx::query!(
r#"
select
diff --git a/src/channel/routes.rs b/src/channel/routes.rs
index 23c0602..5d67af8 100644
--- a/src/channel/routes.rs
+++ b/src/channel/routes.rs
@@ -2,56 +2,21 @@ use axum::{
extract::{Json, Path, State},
http::StatusCode,
response::{IntoResponse, Response},
- routing::{delete, get, post},
+ routing::{delete, post},
Router,
};
-use axum_extra::extract::Query;
use super::{app, Channel, Id};
-use crate::{
- app::App,
- clock::RequestedAt,
- error::Internal,
- event::{Instant, Sequence},
- login::Login,
- message::{self, app::SendError},
-};
+use crate::{app::App, clock::RequestedAt, error::Internal, login::Login, message::app::SendError};
#[cfg(test)]
mod test;
pub fn router() -> Router<App> {
Router::new()
- .route("/api/channels", get(list))
.route("/api/channels", post(on_create))
.route("/api/channels/:channel", post(on_send))
.route("/api/channels/:channel", delete(on_delete))
- .route("/api/channels/:channel/messages", get(messages))
-}
-
-#[derive(Default, serde::Deserialize)]
-struct ResumeQuery {
- resume_point: Option<Sequence>,
-}
-
-async fn list(
- State(app): State<App>,
- _: Login,
- Query(query): Query<ResumeQuery>,
-) -> Result<Channels, Internal> {
- let channels = app.channels().all(query.resume_point).await?;
- let response = Channels(channels);
-
- Ok(response)
-}
-
-struct Channels(Vec<Channel>);
-
-impl IntoResponse for Channels {
- fn into_response(self) -> Response {
- let Self(channels) = self;
- Json(channels).into_response()
- }
}
#[derive(Clone, serde::Deserialize)]
@@ -150,53 +115,3 @@ impl IntoResponse for ErrorResponse {
}
}
}
-
-async fn messages(
- State(app): State<App>,
- Path(channel): Path<Id>,
- _: Login,
- Query(query): Query<ResumeQuery>,
-) -> Result<Messages, ErrorResponse> {
- let messages = app
- .channels()
- .messages(&channel, query.resume_point)
- .await?;
- let response = Messages(
- messages
- .into_iter()
- .map(|message| MessageView {
- sent: message.sent,
- sender: message.sender,
- message: MessageInner {
- id: message.id,
- body: message.body,
- },
- })
- .collect(),
- );
-
- Ok(response)
-}
-
-struct Messages(Vec<MessageView>);
-
-#[derive(serde::Serialize)]
-struct MessageView {
- #[serde(flatten)]
- sent: Instant,
- sender: Login,
- message: MessageInner,
-}
-
-#[derive(serde::Serialize)]
-struct MessageInner {
- id: message::Id,
- body: String,
-}
-
-impl IntoResponse for Messages {
- fn into_response(self) -> Response {
- let Self(messages) = self;
- Json(messages).into_response()
- }
-}
diff --git a/src/channel/routes/test/list.rs b/src/channel/routes/test/list.rs
deleted file mode 100644
index f15a53c..0000000
--- a/src/channel/routes/test/list.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use axum::extract::State;
-use axum_extra::extract::Query;
-
-use crate::{channel::routes, test::fixtures};
-
-#[tokio::test]
-async fn empty_list() {
- // Set up the environment
-
- let app = fixtures::scratch_app().await;
- let viewer = fixtures::login::create(&app).await;
-
- // Call the endpoint
-
- let routes::Channels(channels) = routes::list(State(app), viewer, Query::default())
- .await
- .expect("always succeeds");
-
- // Verify the semantics
-
- assert!(channels.is_empty());
-}
-
-#[tokio::test]
-async fn one_channel() {
- // Set up the environment
-
- let app = fixtures::scratch_app().await;
- let viewer = fixtures::login::create(&app).await;
- let channel = fixtures::channel::create(&app, &fixtures::now()).await;
-
- // Call the endpoint
-
- let routes::Channels(channels) = routes::list(State(app), viewer, Query::default())
- .await
- .expect("always succeeds");
-
- // Verify the semantics
-
- assert!(channels.contains(&channel));
-}
-
-#[tokio::test]
-async fn multiple_channels() {
- // Set up the environment
-
- let app = fixtures::scratch_app().await;
- let viewer = fixtures::login::create(&app).await;
- let channels = vec![
- fixtures::channel::create(&app, &fixtures::now()).await,
- fixtures::channel::create(&app, &fixtures::now()).await,
- ];
-
- // Call the endpoint
-
- let routes::Channels(response_channels) = routes::list(State(app), viewer, Query::default())
- .await
- .expect("always succeeds");
-
- // Verify the semantics
-
- assert!(channels
- .into_iter()
- .all(|channel| response_channels.contains(&channel)));
-}
diff --git a/src/channel/routes/test/mod.rs b/src/channel/routes/test/mod.rs
index ab663eb..3e5aa17 100644
--- a/src/channel/routes/test/mod.rs
+++ b/src/channel/routes/test/mod.rs
@@ -1,3 +1,2 @@
-mod list;
mod on_create;
mod on_send;
diff --git a/src/channel/routes/test/on_create.rs b/src/channel/routes/test/on_create.rs
index 5733c9e..ed49017 100644
--- a/src/channel/routes/test/on_create.rs
+++ b/src/channel/routes/test/on_create.rs
@@ -33,8 +33,11 @@ async fn new_channel() {
// Verify the semantics
- let channels = app.channels().all(None).await.expect("always succeeds");
- assert!(channels.contains(&response_channel));
+ let snapshot = app.boot().snapshot().await.expect("boot always succeeds");
+ assert!(snapshot
+ .channels
+ .iter()
+ .any(|channel| channel.name == response_channel.name && channel.id == response_channel.id));
let mut events = app
.events()