Generic functions are not currently supported as Dropshot endpoints. This capability would be useful for writing generic Dropshot interfaces over traits. A minimum reproducible example is provided below.
In the mean time, the error message that comes up when this is attempted should be something to the effect of "generic endpoints are not currently supported". The error that comes up now (below) does not make it clear what's going on.
Example:
use std::sync::Arc;
use dropshot::{
endpoint,
ConfigDropshot,
ConfigLogging,
ConfigLoggingLevel,
ApiDescription,
HttpServerStarter,
RequestContext,
HttpResponseOk,
HttpError,
};
trait Greeter {
fn say_hello(&self) -> String;
}
struct Context<G: Greeter + std::marker::Send + std::marker::Sync + 'static> {
greeter: G,
}
#[endpoint { method = GET, path = "/greet" }]
async fn greet<G: Greeter + std::marker::Send + std::marker::Sync + 'static>(
ctx: Arc<RequestContext<Context<G>>>
) -> Result<HttpResponseOk<String>, HttpError> {
let api_context = ctx.context();
Ok(HttpResponseOk(api_context.greeter.say_hello()))
}
#[tokio::main]
async fn main() -> Result<(), String> {
let log =
ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info }
.to_logger("minimal-example")
.map_err(|e| e.to_string())?;
let mut api = ApiDescription::new();
// I realize this bit is going to be tricky, as the concrete type to make this an
// instantiated function does not come until the HttpServerStarter::new call
// when we pass in the Context with the specific Greeter implementation
api.register(greet).unwrap();
let api_context = Context{ greeter: Mandarin{} };
let server = HttpServerStarter::new(
&ConfigDropshot { ..Default::default() },
api,
api_context,
&log,
).expect("server new").start();
server.await
}
struct Mandarin {}
impl Greeter for Mandarin {
fn say_hello(&self) -> String { "你好".to_string() }
}
struct English{}
impl Greeter for English {
fn say_hello(&self) -> String { "hello".to_string() }
}
Which produces the compiler error
error[E0412]: cannot find type `G` in this scope
--> src/main.rs:24:37
|
24 | ctx: Arc<RequestContext<Context<G>>>
| ^ - help: you might be missing a type parameter: `<G>`
| |
| not found in this scope
error[E0412]: cannot find type `G` in this scope
--> src/main.rs:24:37
|
24 | ctx: Arc<RequestContext<Context<G>>>
| ^ not found in this scope
error[E0277]: the trait bound `ApiEndpoint<_>: From<greet>` is not satisfied
--> src/main.rs:41:9
|
41 | api.register(greet).unwrap();
| ^^^^^^^^ the trait `From<greet>` is not implemented for `ApiEndpoint<_>`
|
= note: required because of the requirements on the impl of `Into<ApiEndpoint<_>>` for `greet`
Some errors have detailed explanations: E0277, E0412.
For more information about an error, try `rustc --explain E0277`.
Generic functions are not currently supported as Dropshot endpoints. This capability would be useful for writing generic Dropshot interfaces over traits. A minimum reproducible example is provided below.
In the mean time, the error message that comes up when this is attempted should be something to the effect of "generic endpoints are not currently supported". The error that comes up now (below) does not make it clear what's going on.
Example:
Which produces the compiler error