1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::sync::Arc;

use async_trait::async_trait;
use http::Response;
use hyper::Body;

use hyper_fast::server::{ApiError, HttpResponse, HttpRoute, Service};
use hyper_fast::server::{ServiceBuilder, ServiceDaemon, start_http_server};
#[cfg(feature = "settings")]
use hyper_fast::server::utils::load_config;
#[cfg(any(feature = "access_log", feature = "metrics"))]
use hyper_fast::server::utils::setup_logging;

#[cfg(feature = "uring")]
fn main() -> Result<(), anyhow::Error> {
    tokio_uring::start(main_inner())?;

    Ok(())
}

#[cfg(not(feature = "uring"))]
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
    main_inner().await
}

async fn main_inner() -> Result<(), anyhow::Error> {
    #[cfg(feature = "settings")]
    load_config("examples/config", "dev")?;

    #[cfg(any(feature = "access_log"))]
    setup_logging("examples/config/log4rs.yml")?;

    start_http_server("127.0.0.1:6464", ExampleServiceBuilder {}).await
}

pub struct ExampleService {
    // any service level properties
}

pub struct ExampleServiceDaemon {}

pub struct ExampleServiceBuilder {
    // any service builder level properties
}

#[async_trait]
impl ServiceDaemon<ExampleService> for ExampleServiceDaemon {
    async fn start(&self, _service: Arc<ExampleService>) {
        //no impl for now.
    }
}

#[async_trait]
impl ServiceBuilder<ExampleService, ExampleServiceDaemon> for ExampleServiceBuilder {
    async fn build(self) -> anyhow::Result<(ExampleService, Option<ExampleServiceDaemon>)> {
        let service = ExampleService {};

        Ok((service, None))
    }
}

#[async_trait]
impl Service for ExampleService {
    async fn api_handler<'a>(
        &'a self,
        _: Body,
        route: &HttpRoute<'a>,
        path: &[&str],
    ) -> Result<Response<Body>, ApiError> {
        match path {
            ["test"] if matches!(route.method, &http::Method::GET) => {
                self.get_test(route).await
            }
            _ => HttpResponse::not_found(route.path),
        }
    }
}

impl ExampleService {
    pub async fn get_test(&self, route: &HttpRoute<'_>) -> Result<Response<Body>, ApiError> {
        HttpResponse::string(route, "GET::/api/test - test passed".to_string())
    }
}