pub fn server_configured<R, O, C, S, Fut, B>(
    service: S
) -> impl ResourceConsumer<HyperServer<R>, O, C>where
    C: Send + Sync + 'static,
    O: Send + Sync + 'static,
    R: ResourceConfig<O, C>,
    R::Resource: IntoIncoming,
    <R::Resource as IntoIncoming>::Connection: AsyncRead + AsyncWrite,
    S: Fn(&Arc<Spirit<O, C>>, &Arc<HyperServer<R>>, Request<Body>) -> Fut + Clone + Send + Sync + 'static,
    Fut: IntoFuture<Item = Response<B>> + Send + 'static,
    Fut::Future: Send + 'static,
    Fut::Error: Into<Box<dyn Error + Send + Sync>>,
    B: Payload,
Expand description

Like server, but taking a closure to answer request directly.

The closure taken is Fn(spirit, cfg, request) -> impl Future<Response>.

If the configuration is not needed, the server_simple or server_ok might be an alternative.

Examples

extern crate hyper;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate spirit;
extern crate spirit_hyper;
extern crate spirit_tokio;

use std::collections::HashSet;
use std::sync::Arc;

use hyper::{Body, Request, Response};
use spirit::{Empty, Spirit};
use spirit_tokio::ExtraCfgCarrier;
use spirit_hyper::HttpServer;

const DEFAULT_CONFIG: &str = r#"
[[server]]
port = 3456

[ui]
msg = "Hello world"
"#;


#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Hash)]
struct Signature {
    signature: Option<String>,
}

#[derive(Default, Deserialize)]
struct Ui {
    msg: String,
}

#[derive(Default, Deserialize)]
struct Config {
    /// On which ports (and interfaces) to listen.
    ///
    /// With some additional configuration about listening, the http server...
    ///
    /// Also, signature of the given listening port.
    #[serde(default)]
    listen: HashSet<HttpServer<Signature>>,
    /// The UI (there's only the message to send).
    ui: Ui,
}

impl Config {
    /// A function to extract the HTTP servers configuration
    fn listen(&self) -> HashSet<HttpServer<Signature>> {
        self.listen.clone()
    }
}

fn hello(
    spirit: &Arc<Spirit<Empty, Config>>,
    cfg: &Arc<HttpServer<Signature>>,
   _req: Request<Body>,
) -> Result<Response<Body>, std::io::Error> {
    // Get some global configuration
    let mut msg = format!("{}\n", spirit.config().ui.msg);
    // Get some listener-local configuration.
    if let Some(ref signature) = cfg.extra().signature {
        msg.push_str(&format!("Brought to you by {}\n", signature));
    }
    Ok(Response::new(Body::from(msg)))
}

fn main() {
    Spirit::<Empty, Config>::new()
        .config_defaults(DEFAULT_CONFIG)
        .with(spirit_tokio::resources(
            Config::listen,
            spirit_hyper::server_configured(hello),
            "server",
        ))
        .run(|spirit| {
            Ok(())
        });
}