I am writing the rust code of an axum endpoint. This endpoint fetches data from a db. I then want to create futures to call an API using these data (so that I can send all queries at once). It is not fully finished but the syntax seems correct, but weirdly it doesn't compile with an error I don't understand.
Here is my code:
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<AddrQuery>,
) -> impl IntoResponse {
let id_owners = state
.starknetid_db
.collection::<mongodb::bson::Document>("id_owners");
let pipeline = [
// mongodb pipeline
];
let aggregate_options = AggregateOptions::default();
let cursor = id_owners.aggregate(pipeline, aggregate_options).await;
match cursor {
Ok(mut cursor) => {
let mut temp_full_ids = Vec::new();
while let Some(doc) = cursor.next().await {
if let Ok(doc) = doc {
let id = FieldElement::from_hex_be(
&doc.get_str("id").unwrap_or_default().to_owned(),
)
.unwrap()
.to_string();
let domain = doc.get_str("domain").ok().map(String::from);
let domain_expiry = doc.get_i32("domain_expiry").ok();
let pp_verifier_data = doc.get_array("pp_verifier_data").ok();
let mut pp_url_future: Option<Pin<Box<dyn Future<Output = Option<String>>>>> =
None;
if let Some(data) = pp_verifier_data {
if data.len() >= 2 {
if let (Some(contract_data), Some(id_data)) = (data.get(0), data.get(1))
{
if let (Bson::Document(contract_doc), Bson::Document(id_doc)) =
(contract_data, id_data)
{
if let (Ok(contract_str), Ok(data_id)) = (
contract_doc.get_str("data"),
id_doc.get_array("extended_data"),
) {
let id_felts: Vec<String> = data_id
.into_iter()
.map(|b| match b {
Bson::String(s) => s.to_owned(),
_ => b.to_string(),
})
.collect();
let id = to_u256(
id_felts.get(0).unwrap(),
id_felts.get(1).unwrap(),
)
.to_string();
let api_url = state.conf.starkscan.api_url.clone();
let api_key = state.conf.starkscan.api_key.clone();
let contract_str = contract_str.to_string();
let id = id.to_string();
pp_url_future = Some(Box::pin(async move {
fetch_img_url(&api_url, &api_key, contract_str, id)
.await
})
as Pin<Box<dyn Future<Output = Option<String>>>>);
}
}
}
}
}
temp_full_ids.push(TempsFullId {
id,
domain,
domain_expiry,
pp_url_future,
});
}
}
let response = FullIdResponse {
full_ids: temp_full_ids
.iter()
.map(|id| FullId {
id: id.id.clone(),
domain: id.domain.clone(),
domain_expiry: id.domain_expiry,
pp_url: None,
})
.collect::<Vec<FullId>>(),
};
(StatusCode::OK, Json(response)).into_response()
}
Err(_) => get_error("Error while fetching from database".to_string()),
}
}
And on my router, when trying to add the route:
.route(
"/addr_to_full_ids",
get(endpoints::addr_to_full_ids::handler),
)
I get:
Compiling starknetid_server v0.1.0 (/Users/thomas/starknetid/api.starknet.id)
error[E0277]: the trait bound `fn(axum::extract::State<Arc<AppState>>, Query<addr_to_full_ids::AddrQuery>) -> impl futures::Future<Output = impl IntoResponse> {addr_to_full_ids::handler}: Handler<_, _, _>` is not satisfied
--> src/main.rs:66:17
|
66 | get(endpoints::addr_to_full_ids::handler),
| --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::extract::State<Arc<AppState>>, Query<addr_to_full_ids::AddrQuery>) -> impl futures::Future<Output = impl IntoResponse> {addr_to_full_ids::handler}`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Handler<T, S, B>`:
<Layered<L, H, T, S, B, B2> as Handler<T, S, B2>>
<MethodRouter<S, B> as Handler<(), S, B>>
note: required by a bound in `axum::routing::get`
--> /Users/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.6.18/src/routing/method_routing.rs:403:1
|
403 | top_level_handler_fn!(get, GET);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `get`
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `starknetid_server` (bin "starknetid_server") due to previous error