use dropshot::endpoint;
use dropshot::ApiDescription;
use dropshot::ConfigLogging;
use dropshot::ConfigLoggingLevel;
use dropshot::HttpError;
use dropshot::HttpResponseOk;
use dropshot::HttpResponseUpdatedNoContent;
use dropshot::RequestContext;
use dropshot::ServerBuilder;
use dropshot::TypedBody;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
#[tokio::main]
async fn main() -> Result<(), String> {
let config_logging =
ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info };
let log = config_logging
.to_logger("example-basic")
.map_err(|error| format!("failed to create logger: {}", error))?;
let mut api = ApiDescription::new();
api.register(example_api_get_counter).unwrap();
api.register(example_api_put_counter).unwrap();
let api_context = ExampleContext::new();
let server = ServerBuilder::new(api, api_context, log)
.start()
.map_err(|error| format!("failed to create server: {}", error))?;
server.await
}
struct ExampleContext {
counter: AtomicU64,
}
impl ExampleContext {
pub fn new() -> ExampleContext {
ExampleContext { counter: AtomicU64::new(0) }
}
}
#[derive(Deserialize, Serialize, JsonSchema)]
struct CounterValue {
counter: u64,
}
#[endpoint {
method = GET,
path = "/counter",
}]
async fn example_api_get_counter(
rqctx: RequestContext<ExampleContext>,
) -> Result<HttpResponseOk<CounterValue>, HttpError> {
let api_context = rqctx.context();
Ok(HttpResponseOk(CounterValue {
counter: api_context.counter.load(Ordering::SeqCst),
}))
}
#[endpoint {
method = PUT,
path = "/counter",
}]
async fn example_api_put_counter(
rqctx: RequestContext<ExampleContext>,
update: TypedBody<CounterValue>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let api_context = rqctx.context();
let updated_value = update.into_inner();
if updated_value.counter == 10 {
Err(HttpError::for_bad_request(
Some(String::from("BadInput")),
format!("do not like the number {}", updated_value.counter),
))
} else {
api_context.counter.store(updated_value.counter, Ordering::SeqCst);
Ok(HttpResponseUpdatedNoContent())
}
}