use anyhow::{Context, Result};
use rave_engine::types::entries::{
CodeTemplate, EARole, ExecutionEngine, ExecutorRules, InputRules,
};
use serde::{Deserialize, Serialize};
use std::{fs, path::PathBuf};
#[derive(Debug, Serialize, Deserialize)]
pub struct ExecutableAgreementLib {
#[serde(default)]
pub title: String,
pub input_rules: InputRules,
pub executor_rules: ExecutorRules,
pub one_time_run: bool,
pub aggregate_execution: bool,
pub roles: Vec<EARole>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SystemTemplateConfig {
pub template: CodeTemplate,
pub agreements: Vec<ExecutableAgreementLib>,
}
impl SystemTemplateConfig {
pub fn load(library_path: String) -> Result<Vec<SystemTemplateConfig>> {
let path = PathBuf::from(library_path);
let mut templates = Vec::new();
for entry in fs::read_dir(path)? {
let entry = entry?;
if entry.file_type()?.is_dir() {
let template_path = entry.path().join("execution_code.rhai");
if template_path.exists() {
let code = fs::read_to_string(&template_path)
.context(format!("Failed to read {}", template_path.display()))?;
let code = rmp_serde::encode::to_vec(&code).unwrap();
let input_signature = serde_json::from_str(&fs::read_to_string(
&entry.path().join("input_signature.json"),
)?)?;
let output_signature = serde_json::from_str(&fs::read_to_string(
&entry.path().join("output_signature.json"),
)?)?;
let template = CodeTemplate {
title: entry.file_name().to_string_lossy().to_string(),
execution_code: code,
execution_engine: ExecutionEngine::Rhai,
input_signature,
output_signature,
};
let agreements_path = entry.path().join("agreements");
let mut agreements = Vec::new();
if fs::metadata(&agreements_path)?.is_dir() {
for entry in fs::read_dir(agreements_path)? {
let entry = entry?;
if let Ok(agreement) =
serde_json::from_str(&fs::read_to_string(&entry.path())?)
{
agreements.push(agreement);
}
}
}
templates.push(SystemTemplateConfig {
template,
agreements,
});
}
}
}
Ok(templates)
}
}