From f4de34eefe95cead9527557abcfddc2648d30278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kot?= Date: Sat, 26 Jun 2021 15:32:44 +0200 Subject: Add example implementation using async source Signed-off-by: Matthias Beyer Reviewed-by: Matthias Beyer --- examples/async_source/main.rs | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 examples/async_source/main.rs (limited to 'examples') diff --git a/examples/async_source/main.rs b/examples/async_source/main.rs new file mode 100644 index 0000000..979f829 --- /dev/null +++ b/examples/async_source/main.rs @@ -0,0 +1,75 @@ +use std::{collections::HashMap, error::Error}; + +use config::{builder::AsyncState, AsyncSource, ConfigBuilder, ConfigError, FileFormat}; + +use async_trait::async_trait; +use futures::{select, FutureExt}; +use warp::Filter; + +// Example below presents sample configuration server and client. +// +// Server serves simple configuration on HTTP endpoint. +// Client consumes it using custom HTTP AsyncSource built on top of reqwest. + +#[tokio::main] +async fn main() -> Result<(), Box> { + select! { + r = run_server().fuse() => r, + r = run_client().fuse() => r + } +} + +async fn run_server() -> Result<(), Box> { + let service = warp::path("configuration").map(|| r#"{ "value" : 123 }"#); + + println!("Running server on localhost:5001"); + + warp::serve(service).bind(([127, 0, 0, 1], 5001)).await; + + Ok(()) +} + +async fn run_client() -> Result<(), Box> { + // Good enough for an example to allow server to start + tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; + + let config = ConfigBuilder::::default() + .add_async_source(HttpSource { + uri: "http://localhost:5001/configuration".into(), + format: FileFormat::Json, + }) + .build() + .await?; + + println!("Config value is {}", config.get::("value")?); + + Ok(()) +} + +// Actual implementation of AsyncSource can be found below + +#[derive(Debug)] +struct HttpSource { + uri: String, + format: FileFormat, +} + +impl HttpSource { + async fn call(&self) -> Result { + reqwest::get(&self.uri).await?.text().await + } +} + +#[async_trait] +impl AsyncSource for HttpSource { + async fn collect(&self) -> Result, ConfigError> { + self.call() + .await + .map_err(|e| ConfigError::Foreign(Box::new(e))) + .and_then(|text| { + self.format + .parse(Some(&self.uri), &text) + .map_err(|e| ConfigError::Foreign(e)) + }) + } +} -- cgit v1.2.3