use serde_json::Value;
use crate::permission::{evaluate, Context, Doc, RoleRules};
use crate::schema::Schema;
use super::super::cache::{ensure_cache, ComputeEntry};
use super::super::registry::FnRegistry;
pub fn select_async_fns(
rules: &RoleRules,
schema: &Schema,
ctx: Option<&Context>,
) -> Vec<ComputeEntry> {
let cache = ensure_cache(schema);
if cache.async_fn_list.is_empty() {
return Vec::new();
}
let mut selected: Vec<ComputeEntry> = Vec::new();
match ctx {
None => selected.extend(cache.async_fn_list.iter().cloned()),
Some(c) => {
for entry in &cache.async_fn_list {
let rl = schema
.compute(&entry.key)
.and_then(|comp| comp.read.as_ref());
match rl {
Some(roles) => {
if evaluate(rules, Some(c), Some(roles), Doc::Missing) {
selected.push(entry.clone());
}
}
None => selected.push(entry.clone()),
}
}
}
}
selected
}
pub fn run_async_fns(
items: &mut [Value],
rules: &RoleRules,
schema: &Schema,
ctx: Option<&Context>,
fn_registry: Option<&dyn FnRegistry>,
) -> Result<(), String> {
if items.is_empty() {
return Ok(());
}
for entry in select_async_fns(rules, schema, ctx) {
match fn_registry {
Some(r) => r.call_async(&entry.fn_ref, items, ctx)?,
None => return Err(format!("计算列 {} 未注册异步实现", entry.key)),
}
}
Ok(())
}