use std::sync::OnceLock;
use apcore::{APCore, Context, Identity, Module};
use serde_json::{json, Value};
static CLIENT: OnceLock<APCore> = OnceLock::new();
fn client() -> &'static APCore {
CLIENT.get_or_init(APCore::new)
}
struct AddModule;
#[async_trait::async_trait]
impl Module for AddModule {
fn input_schema(&self) -> Value {
json!({
"type": "object",
"properties": {
"a": { "type": "integer" },
"b": { "type": "integer" }
},
"required": ["a", "b"]
})
}
fn output_schema(&self) -> Value {
json!({
"type": "object",
"properties": {
"result": { "type": "integer" }
},
"required": ["result"]
})
}
fn description(&self) -> &'static str {
"Add two integers"
}
async fn execute(
&self,
inputs: Value,
_ctx: &Context<Value>,
) -> Result<Value, apcore::errors::ModuleError> {
let a = inputs["a"].as_i64().unwrap_or(0);
let b = inputs["b"].as_i64().unwrap_or(0);
Ok(json!({ "result": a + b }))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
client().register("math.add", Box::new(AddModule))?;
let ctx = Context::new(Identity::new(
"user:1".into(),
"user".into(),
vec![],
std::collections::HashMap::new(),
));
let result = client()
.call("math.add", json!({"a": 10, "b": 5}), Some(&ctx), None)
.await?;
println!("Global call result: {result}");
let result2 = client()
.call("math.add", json!({"a": 100, "b": 200}), None, None)
.await?;
println!("Second call result: {result2}");
let modules = client().list_modules(None, None);
println!("Registered modules: {modules:?}");
Ok(())
}