Add server implementation

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
commit 3a7d9111bc
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

1
.gitignore vendored

@ -0,0 +1 @@
/target

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/multihook.iml" filepath="$PROJECT_DIR$/.idea/multihook.iml" />
</modules>
</component>
</project>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

1056
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,14 @@
[package]
name = "multihook"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
warp = "0.3.1"
thiserror = "1.0.26"
[dependencies.tokio]
version = "1.9.0"
features = ["macros", "rt-multi-thread", "process"]

@ -0,0 +1,9 @@
use crate::error::MultihookResult;
pub enum HookAction {}
impl HookAction {
pub async fn execute(&self, body: &str) -> MultihookResult<()> {
Ok(())
}
}

@ -0,0 +1,19 @@
use std::string::FromUtf8Error;
use thiserror::Error;
use warp::reject::Reject;
pub type MultihookResult<T> = Result<T, MultihookError>;
#[derive(Error, Debug)]
pub enum MultihookError {
#[error(transparent)]
Warp(#[from] warp::Error),
#[error("Failed to parse body as utf8 string {0}")]
UTF8Error(#[from] FromUtf8Error),
#[error("Unknown endpoint")]
UnknownEndpoint,
}
impl Reject for MultihookError {}

@ -0,0 +1,7 @@
mod server;
mod action;
mod error;
fn main() {
println!("Hello, world!");
}

@ -0,0 +1,49 @@
use crate::action::HookAction;
use crate::error::{MultihookError, MultihookResult};
use std::collections::HashMap;
use std::sync::Arc;
use warp::hyper::body::Bytes;
use warp::{Filter, Rejection};
pub struct HookServer {
endpoints: HashMap<String, HookAction>,
}
impl HookServer {
pub fn add_hook(&mut self, point: String, action: HookAction) {
self.endpoints.insert(point, action);
}
async fn execute_action(
body: Bytes,
point: String,
action: Arc<HookAction>,
) -> Result<impl warp::Reply, Rejection> {
let body = String::from_utf8(body.to_vec()).map_err(MultihookError::from)?;
action.execute(&body).await?;
Ok(format!("Hook {} executed", point))
}
pub fn start(self) {
let routes = self
.endpoints
.into_iter()
.map(|(p, a)| (p, Arc::new(a)))
.map(|(point, action)| {
warp::post()
.and(warp::path(point.clone()))
.and(warp::body::bytes())
.and_then(move |b| {
let action = Arc::clone(&action);
Self::execute_action(b, point.clone(), action)
})
.map(|_| warp::reply())
.boxed()
})
.fold(warp::any().map(warp::reply).boxed(), |routes, route| {
routes.or(route).unify().boxed()
});
let routes = warp::serve(routes);
}
}
Loading…
Cancel
Save