Skip to main content

loong_kernel/
harness.rs

1use std::{collections::BTreeMap, sync::Arc};
2
3use async_trait::async_trait;
4
5use crate::{
6    contracts::{ExecutionRoute, HarnessKind, HarnessOutcome, HarnessRequest},
7    errors::HarnessError,
8};
9
10#[async_trait]
11pub trait HarnessAdapter: Send + Sync {
12    fn name(&self) -> &str;
13    fn kind(&self) -> HarnessKind;
14    async fn execute(&self, request: HarnessRequest) -> Result<HarnessOutcome, HarnessError>;
15}
16
17#[derive(Default)]
18pub struct HarnessBroker {
19    adapters: BTreeMap<String, Arc<dyn HarnessAdapter>>,
20}
21
22impl HarnessBroker {
23    #[must_use]
24    pub fn new() -> Self {
25        Self {
26            adapters: BTreeMap::new(),
27        }
28    }
29
30    pub fn register<A: HarnessAdapter + 'static>(&mut self, adapter: A) {
31        let key = adapter.name().to_owned();
32        self.adapters.insert(key, Arc::new(adapter));
33    }
34
35    pub async fn execute(
36        &self,
37        route: &ExecutionRoute,
38        request: HarnessRequest,
39    ) -> Result<HarnessOutcome, HarnessError> {
40        let adapter = if let Some(adapter_name) = &route.adapter {
41            self.adapters
42                .get(adapter_name)
43                .ok_or_else(|| HarnessError::AdapterNotFound(adapter_name.clone()))?
44                .clone()
45        } else {
46            self.adapters
47                .values()
48                .find(|candidate| candidate.kind() == route.harness_kind)
49                .cloned()
50                .ok_or_else(|| {
51                    HarnessError::AdapterNotFound(format!("kind::{:?}", route.harness_kind))
52                })?
53        };
54
55        if adapter.kind() != route.harness_kind {
56            return Err(HarnessError::AdapterKindMismatch {
57                adapter: adapter.name().to_owned(),
58                expected: route.harness_kind,
59                actual: adapter.kind(),
60            });
61        }
62
63        return adapter.execute(request).await;
64    }
65}