Alexey Velikiy
3 years ago
4 changed files with 87 additions and 64 deletions
@ -1,71 +1,84 @@
|
||||
use hastic::services::data_service::{self, Segment}; |
||||
mod filters { |
||||
use warp::Filter; |
||||
use super::models::{Db, ListOptions}; |
||||
use super::handlers; |
||||
|
||||
|
||||
use warp::filters::method::get; |
||||
use warp::http::HeaderValue; |
||||
use warp::hyper::{Body, StatusCode}; |
||||
use warp::reject::Reject; |
||||
use warp::{http::Response, Filter}; |
||||
use warp::{Rejection, Reply}; |
||||
/// The 4 REST API filters combined.
|
||||
pub fn filters( |
||||
db: Db, |
||||
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone { |
||||
list(db.clone()) |
||||
.or(create(db.clone())) |
||||
// .or(update(db.clone()))
|
||||
// .or(delete(db.clone()))
|
||||
} |
||||
|
||||
use serde::Serialize; |
||||
/// GET /segments?from=3&to=5
|
||||
pub fn list( |
||||
db: Db, |
||||
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone { |
||||
warp::path!("segments") |
||||
.and(warp::get()) |
||||
.and(warp::query::<ListOptions>()) |
||||
.and(with_db(db)) |
||||
.and_then(handlers::list) |
||||
} |
||||
|
||||
use crate::api::{self, API}; |
||||
/// POST /segments with JSON body
|
||||
pub fn create( |
||||
db: Db |
||||
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone { |
||||
warp::path!("segments") |
||||
.and(warp::post()) |
||||
.and(warp::body::json()) |
||||
.and(with_db(db)) |
||||
.and_then(handlers::create) |
||||
} |
||||
|
||||
use parking_lot::RwLock; |
||||
use std::collections::HashMap; |
||||
use std::sync::Arc; |
||||
fn with_db(db: Db) -> impl Filter<Extract = (Db,), Error = std::convert::Infallible> + Clone { |
||||
warp::any().map(move || db.clone()) |
||||
} |
||||
|
||||
#[derive(Serialize)] |
||||
struct SegmentsResult { |
||||
segments: Vec<Segment> |
||||
} |
||||
|
||||
#[derive(Debug)] |
||||
struct BadQuery; |
||||
|
||||
impl Reject for BadQuery {} |
||||
|
||||
mod handlers { |
||||
use hastic::services::data_service; |
||||
|
||||
use crate::api::API; |
||||
use crate::api::BadQuery; |
||||
use super::models::ListOptions; |
||||
use super::models::Db; |
||||
|
||||
async fn get_query( |
||||
p: HashMap<String, String>, |
||||
ds: Arc<RwLock<data_service::DataService>>, |
||||
) -> anyhow::Result<SegmentsResult> { |
||||
if !p.contains_key("from") { |
||||
return Err(anyhow::anyhow!("Missing attribute from")); |
||||
pub async fn list(opts: ListOptions, db: Db) -> Result<impl warp::Reply, warp::Rejection> { |
||||
// Just return a JSON array of todos, applying the limit and offset.
|
||||
match db.read().get_segments(opts.from, opts.to) { |
||||
Ok(segments) => Ok(API::json(&segments)), |
||||
Err(e) => Err(warp::reject::custom(BadQuery)) |
||||
} |
||||
} |
||||
if !p.contains_key("to") { |
||||
return Err(anyhow::anyhow!("Missing attribute to")); |
||||
|
||||
pub async fn create(segment: data_service::Segment, db: Db) -> Result<impl warp::Reply, warp::Rejection> { |
||||
// Just return a JSON array of todos, applying the limit and offset.
|
||||
match db.write().insert_segment(&segment) { |
||||
Ok(segments) => Ok(API::json(&segments)), |
||||
Err(e) => Err(warp::reject::custom(BadQuery)) |
||||
} |
||||
} |
||||
let from = p.get("from").unwrap().parse::<u64>()?; |
||||
let to = p.get("to").unwrap().parse::<u64>()?; |
||||
} |
||||
|
||||
let res = ds.read().get_segments(from, to)?; |
||||
drop(ds); |
||||
mod models { |
||||
use serde::{Deserialize}; |
||||
use hastic::services::data_service; |
||||
use parking_lot::RwLock; |
||||
use std::sync::Arc; |
||||
|
||||
Ok(SegmentsResult{ segments: res }) |
||||
// Ok(prom.query(from, to, step).await?)
|
||||
} |
||||
pub type Db = Arc<RwLock<data_service::DataService>>; |
||||
|
||||
async fn query( |
||||
p: HashMap<String, String>, |
||||
ds: Arc<RwLock<data_service::DataService>>, |
||||
) -> Result<impl warp::Reply, warp::Rejection> { |
||||
//Err(warp::reject::custom(BadQuery));
|
||||
match get_query(p, ds).await { |
||||
Ok(res) => Ok(API::json(&res)), |
||||
// TODO: parse different error types
|
||||
Err(_e) => Err(warp::reject::custom(BadQuery)), |
||||
// The query parameters for list_todos.
|
||||
#[derive(Debug, Deserialize)] |
||||
pub struct ListOptions { |
||||
pub from: u64, |
||||
pub to: u64, |
||||
} |
||||
} |
||||
|
||||
pub fn get_route( |
||||
data_service: Arc<RwLock<data_service::DataService>>, |
||||
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { |
||||
|
||||
return warp::path!("api" / "segments") |
||||
.and(get()) |
||||
.and(warp::query::<HashMap<String, String>>()) |
||||
.and(warp::any().map(move || data_service.clone())) |
||||
.and_then(query); |
||||
} |
||||
} |
Loading…
Reference in new issue