mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-07-08 01:32:41 +08:00
Update
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
/// Routes
|
||||
pub mod route;
|
||||
/// Services
|
||||
pub mod service;
|
||||
/// Traits
|
||||
pub mod traits;
|
||||
/// Version
|
||||
pub mod version;
|
||||
|
||||
29
src/server/route.rs
Normal file
29
src/server/route.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use super::traits::MatchRoute;
|
||||
use super::traits::ResponseFor;
|
||||
use super::version::VersionRoute;
|
||||
use hyper::Body;
|
||||
use hyper::Request;
|
||||
|
||||
pub type RouteType = dyn MatchRoute<Body, Body> + Send + Sync;
|
||||
pub type ResponseForType = dyn ResponseFor<Body, Body> + Send + Sync;
|
||||
|
||||
pub struct ServerRoutes {
|
||||
routes: Vec<Box<RouteType>>,
|
||||
}
|
||||
|
||||
impl ServerRoutes {
|
||||
pub fn new() -> Self {
|
||||
let mut routes: Vec<Box<RouteType>> = Vec::new();
|
||||
routes.push(Box::new(VersionRoute::new()));
|
||||
Self { routes }
|
||||
}
|
||||
|
||||
pub fn match_route(&self, req: &Request<Body>) -> Option<Box<ResponseForType>> {
|
||||
for i in self.routes.iter() {
|
||||
if i.match_route(req) {
|
||||
return Some(i.get_route());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::route::ServerRoutes;
|
||||
use hyper::server::conn::AddrIncoming;
|
||||
use hyper::server::Server;
|
||||
use hyper::service::Service;
|
||||
@@ -7,16 +8,17 @@ use hyper::Response;
|
||||
use std::future::Future;
|
||||
use std::net::SocketAddr;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
pub struct PixivDownloaderSvc {
|
||||
_unused: [u8; 0],
|
||||
routes: Arc<ServerRoutes>,
|
||||
}
|
||||
|
||||
impl PixivDownloaderSvc {
|
||||
pub fn new() -> Self {
|
||||
Self { _unused: [] }
|
||||
pub fn new(routes: Arc<ServerRoutes>) -> Self {
|
||||
Self { routes }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,17 +32,35 @@ impl Service<Request<Body>> for PixivDownloaderSvc {
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
||||
Box::pin(async { Ok(Response::builder().body(Body::from("hello world")).unwrap()) })
|
||||
match self.routes.match_route(&req) {
|
||||
Some(route) => Box::pin(async move {
|
||||
match route.response(req) {
|
||||
Ok(data) => Ok(data),
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
Ok(Response::builder()
|
||||
.status(500)
|
||||
.body(Body::from("Internal server error"))
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
}),
|
||||
None => {
|
||||
Box::pin(async { Ok(Response::builder().body(Body::from("hello world")).unwrap()) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PixivDownloaderMakeSvc {
|
||||
_unused: [u8; 0],
|
||||
routes: Arc<ServerRoutes>,
|
||||
}
|
||||
|
||||
impl PixivDownloaderMakeSvc {
|
||||
pub fn new() -> Self {
|
||||
Self { _unused: [] }
|
||||
Self {
|
||||
routes: Arc::new(ServerRoutes::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +74,8 @@ impl<T> Service<T> for PixivDownloaderMakeSvc {
|
||||
}
|
||||
|
||||
fn call(&mut self, _: T) -> Self::Future {
|
||||
let fut = async move { Ok(PixivDownloaderSvc::new()) };
|
||||
let routes = Arc::clone(&self.routes);
|
||||
let fut = async move { Ok(PixivDownloaderSvc::new(routes)) };
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,25 @@ use hyper::Request;
|
||||
use hyper::Response;
|
||||
use json::JsonValue;
|
||||
|
||||
pub trait MatchRoute<T, R> {
|
||||
fn get_route(&self) -> Box<dyn ResponseFor<T, R> + Send + Sync>;
|
||||
fn match_route(&self, req: &Request<T>) -> bool;
|
||||
}
|
||||
|
||||
pub trait ResponseFor<T, R> {
|
||||
fn response(&self, res: Request<T>) -> Result<Response<R>, PixivDownloaderError>;
|
||||
fn response(&self, req: Request<T>) -> Result<Response<R>, PixivDownloaderError>;
|
||||
}
|
||||
|
||||
pub trait ResponseJsonFor<T> {
|
||||
fn response_json(&self, res: Request<T>) -> Result<JsonValue, PixivDownloaderError>;
|
||||
fn response_json(&self, req: Request<T>) -> Result<JsonValue, PixivDownloaderError>;
|
||||
}
|
||||
|
||||
impl<T> ResponseFor<T, Body> for T
|
||||
impl<T, U> ResponseFor<T, Body> for U
|
||||
where
|
||||
T: ResponseJsonFor<T>,
|
||||
U: ResponseJsonFor<T>,
|
||||
{
|
||||
fn response(&self, res: Request<T>) -> Result<Response<Body>, PixivDownloaderError> {
|
||||
let re = self.response_json(res)?;
|
||||
fn response(&self, req: Request<T>) -> Result<Response<Body>, PixivDownloaderError> {
|
||||
let re = self.response_json(req)?;
|
||||
Ok(Response::new(Body::from(re.to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
46
src/server/version.rs
Normal file
46
src/server/version.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use super::route::ResponseForType;
|
||||
use super::traits::MatchRoute;
|
||||
use super::traits::ResponseJsonFor;
|
||||
use crate::error::PixivDownloaderError;
|
||||
use hyper::Body;
|
||||
use hyper::Request;
|
||||
use json::JsonValue;
|
||||
use regex::Regex;
|
||||
|
||||
pub struct VersionContext {
|
||||
_unused: [u8; 0],
|
||||
}
|
||||
|
||||
impl VersionContext {
|
||||
pub fn new() -> Self {
|
||||
Self { _unused: [] }
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseJsonFor<Body> for VersionContext {
|
||||
fn response_json(&self, _req: Request<Body>) -> Result<JsonValue, PixivDownloaderError> {
|
||||
Ok(json::object! {"version": [0, 0, 1, 0]})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VersionRoute {
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl VersionRoute {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
regex: Regex::new(r"^(/api)?/version(/.*)?$").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MatchRoute<Body, Body> for VersionRoute {
|
||||
fn get_route(&self) -> Box<ResponseForType> {
|
||||
Box::new(VersionContext::new())
|
||||
}
|
||||
|
||||
fn match_route(&self, req: &http::Request<Body>) -> bool {
|
||||
self.regex.is_match(req.uri().path())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user