use async_graphql::{Context, Object, Result};
use crate::types::{
ConfigUpdate, ControlResponse, EpochList, EngineConfig, LibraryList, Status,
};
pub trait EngineProvider: Send + Sync + 'static {
fn status(&self) -> impl std::future::Future<Output = Status> + Send;
fn epochs(
&self,
limit: i32,
offset: i32,
) -> impl std::future::Future<Output = EpochList> + Send;
fn library(&self) -> impl std::future::Future<Output = LibraryList> + Send;
fn config(&self) -> EngineConfig;
fn update_config(&self, update: ConfigUpdate) -> ControlResponse;
fn pause(&self) -> ControlResponse;
fn resume(&self) -> ControlResponse;
}
pub struct QueryRoot;
#[Object]
impl QueryRoot {
async fn status<'ctx>(&self, ctx: &Context<'ctx>) -> Result<Status> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.status().await)
}
async fn epochs<'ctx>(
&self,
ctx: &Context<'ctx>,
#[graphql(default = 50)] limit: i32,
#[graphql(default = 0)] offset: i32,
) -> Result<EpochList> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.epochs(limit, offset).await)
}
async fn library<'ctx>(&self, ctx: &Context<'ctx>) -> Result<LibraryList> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.library().await)
}
async fn config<'ctx>(&self, ctx: &Context<'ctx>) -> Result<EngineConfig> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.config())
}
}
pub struct MutationRoot;
#[Object]
impl MutationRoot {
async fn pause<'ctx>(&self, ctx: &Context<'ctx>) -> Result<ControlResponse> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.pause())
}
async fn resume<'ctx>(&self, ctx: &Context<'ctx>) -> Result<ControlResponse> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.resume())
}
async fn update_config<'ctx>(
&self,
ctx: &Context<'ctx>,
input: ConfigUpdate,
) -> Result<ControlResponse> {
let provider = ctx.data::<Box<dyn EngineProviderDyn>>()?;
Ok(provider.update_config(input))
}
}
#[async_trait::async_trait]
pub trait EngineProviderDyn: Send + Sync {
async fn status(&self) -> Status;
async fn epochs(&self, limit: i32, offset: i32) -> EpochList;
async fn library(&self) -> LibraryList;
fn config(&self) -> EngineConfig;
fn update_config(&self, update: ConfigUpdate) -> ControlResponse;
fn pause(&self) -> ControlResponse;
fn resume(&self) -> ControlResponse;
}
pub type Schema = async_graphql::Schema<QueryRoot, MutationRoot, async_graphql::EmptySubscription>;
pub fn build_schema(provider: Box<dyn EngineProviderDyn>) -> Schema {
async_graphql::Schema::build(QueryRoot, MutationRoot, async_graphql::EmptySubscription)
.data(provider)
.finish()
}