use crate::api;
use crate::bus::{Codec, MessagePack, QueryCode, QueryFailure};
use crate::participant::api::QueryRegistration;
use crate::prelude::*;
struct Api;
#[derive(Default)]
struct QueryState {
calls: Vec<String>,
}
#[phoxal::service(id = "query-test", state = QueryState, api = Api)]
struct QueryParticipant;
impl Participant for QueryParticipant {
async fn setup(
&self,
_ctx: &mut SetupContext<Self>,
_config: Self::Config,
) -> Result<(Self::State, Self::Api)> {
Ok((QueryState::default(), Api))
}
}
impl QueryParticipant {
async fn get(
&self,
_api: &Api,
request: api::asset::GetRequest,
state: &mut QueryState,
) -> QueryResult<api::asset::GetResponse> {
state.calls.push(request.path.clone());
if request.path == "ok" {
Ok(api::asset::GetResponse::Found {
bytes: vec![1, 2, 3],
})
} else {
Err(QueryFailure::not_found("no such asset"))
}
}
}
#[tokio::test]
async fn typed_query_dispatch_decodes_mutates_and_encodes() {
let registration = QueryRegistration::new("v0.1/asset/get".to_string(), QueryParticipant::get);
let participant = QueryParticipant;
let api = Api;
let mut state = QueryState::default();
let first = MessagePack::encode(&api::asset::GetRequest {
path: "ok".to_string(),
})
.unwrap();
let reply = registration
.dispatch(&participant, &api, &mut state, first)
.await
.unwrap();
let response: api::asset::GetResponse = MessagePack::decode(&reply.payload).unwrap();
assert!(matches!(response, api::asset::GetResponse::Found { .. }));
let second = MessagePack::encode(&api::asset::GetRequest {
path: "missing".to_string(),
})
.unwrap();
let failure = registration
.dispatch(&participant, &api, &mut state, second)
.await
.unwrap_err();
assert_eq!(failure.code, QueryCode::NotFound);
assert_eq!(state.calls, ["ok", "missing"]);
}