Skip to content

Commit 7b6b26f

Browse files
committed
sentry - routes - channel - channel_list
1 parent 2d7c714 commit 7b6b26f

File tree

2 files changed

+49
-35
lines changed

2 files changed

+49
-35
lines changed

sentry/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use primitives::Config;
1414
use redis::aio::MultiplexedConnection;
1515
use regex::Regex;
1616
use routes::cfg::config;
17-
use routes::channel::{create_channel, last_approved};
17+
use routes::channel::{channel_list, create_channel, last_approved};
1818
use slog::{error, Logger};
1919
use std::collections::HashMap;
2020

@@ -109,7 +109,7 @@ impl<A: Adapter + 'static> Application<A> {
109109
let mut response = match (req.uri().path(), req.method()) {
110110
("/cfg", &Method::GET) => config(req, &self).await,
111111
("/channel", &Method::POST) => create_channel(req, &self).await,
112-
("/channel/list", &Method::GET) => Err(ResponseError::NotFound),
112+
("/channel/list", &Method::GET) => channel_list(req, &self).await,
113113
// This is important becuase it prevents us from doing
114114
// expensive regex matching for routes without /channel
115115
(route, method) if route.starts_with("/channel") => {

sentry/src/routes/channel.rs

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use self::channel_list::ChannelListQuery;
2-
use crate::db::{get_channel_by_id, insert_channel};
2+
use crate::db::{get_channel_by_id, insert_channel, list_channels, list_channels_total_pages};
3+
use crate::routes::channel::channel_list::ChannelListResponse;
34
use crate::success_response;
45
use crate::Application;
56
use crate::ResponseError;
@@ -62,16 +63,39 @@ pub async fn create_channel<A: Adapter>(
6263
Ok(success_response(serde_json::to_string(&create_response)?))
6364
}
6465

65-
pub async fn channel_list(req: Request<Body>) -> Result<Response<Body>, ResponseError> {
66-
// @TODO: Get from Config
67-
let _channel_find_limit = 5;
68-
66+
pub async fn channel_list<A: Adapter>(
67+
req: Request<Body>,
68+
app: &Application<A>,
69+
) -> Result<Response<Body>, ResponseError> {
6970
let query = serde_urlencoded::from_str::<ChannelListQuery>(&req.uri().query().unwrap_or(""))?;
70-
71-
// @TODO: List all channels returned from the DB
72-
println!("{:?}", query);
73-
74-
Err(ResponseError::NotFound)
71+
let skip = query
72+
.page
73+
.checked_mul(app.config.channels_find_limit.into())
74+
.ok_or_else(|| ResponseError::BadRequest("Page and/or limit is too large".into()))?;
75+
76+
let channels = list_channels(
77+
&app.pool,
78+
skip,
79+
app.config.channels_find_limit,
80+
&query.creator,
81+
&query.validator,
82+
&query.valid_until_ge,
83+
)
84+
.await?;
85+
let total_pages = list_channels_total_pages(
86+
&app.pool,
87+
&query.creator,
88+
&query.validator,
89+
&query.valid_until_ge,
90+
)
91+
.await?;
92+
93+
let list_response = ChannelListResponse {
94+
channels,
95+
total_pages,
96+
};
97+
98+
Ok(success_response(serde_json::to_string(&list_response)?))
7599
}
76100

77101
pub async fn last_approved<A: Adapter>(
@@ -94,39 +118,29 @@ pub async fn last_approved<A: Adapter>(
94118

95119
mod channel_list {
96120
use chrono::{DateTime, Utc};
97-
use serde::{Deserialize, Deserializer};
121+
use primitives::{Channel, ValidatorId};
122+
use serde::{Deserialize, Serialize};
123+
124+
#[derive(Debug, Serialize)]
125+
#[serde(rename_all = "camelCase")]
126+
pub(super) struct ChannelListResponse {
127+
pub channels: Vec<Channel>,
128+
pub total_pages: u64,
129+
}
98130

99131
#[derive(Debug, Deserialize)]
100-
pub(crate) struct ChannelListQuery {
101-
/// page to show, should be >= 1
132+
pub(super) struct ChannelListQuery {
102133
#[serde(default = "default_page")]
103134
pub page: u64,
104-
/// channels limit per page, should be >= 1
105-
#[serde(default = "default_limit")]
106-
pub limit: u32,
107135
/// filters the list on `valid_until >= valid_until_ge`
108136
#[serde(default = "Utc::now")]
109137
pub valid_until_ge: DateTime<Utc>,
138+
pub creator: Option<String>,
110139
/// filters the channels containing a specific validator if provided
111-
#[serde(default, deserialize_with = "deserialize_validator")]
112-
pub validator: Option<String>,
113-
}
114-
115-
/// Deserialize the `Option<String>`, but if the `String` is empty it will return `None`
116-
fn deserialize_validator<'de, D>(de: D) -> Result<Option<String>, D::Error>
117-
where
118-
D: Deserializer<'de>,
119-
{
120-
let value: String = Deserialize::deserialize(de)?;
121-
let option = Some(value).filter(|string| !string.is_empty());
122-
Ok(option)
123-
}
124-
125-
fn default_limit() -> u32 {
126-
1
140+
pub validator: Option<ValidatorId>,
127141
}
128142

129143
fn default_page() -> u64 {
130-
1
144+
0
131145
}
132146
}

0 commit comments

Comments
 (0)