atomr_agents_coding_cli_harness/
store.rs1use std::sync::Arc;
4
5use async_trait::async_trait;
6use dashmap::DashMap;
7
8use atomr_agents_coding_cli_core::{CliResult, CliRunId};
9
10use crate::error::HarnessError;
11
12#[async_trait]
13pub trait CliRunStore: Send + Sync {
14 async fn put(&self, result: &CliResult) -> Result<(), HarnessError>;
15 async fn get(&self, id: &CliRunId) -> Result<Option<CliResult>, HarnessError>;
16 async fn list(&self, limit: usize) -> Result<Vec<CliResult>, HarnessError>;
17}
18
19#[derive(Default, Clone)]
20pub struct InMemoryRunStore {
21 inner: Arc<DashMap<CliRunId, CliResult>>,
22}
23
24impl InMemoryRunStore {
25 pub fn new() -> Self {
26 Self::default()
27 }
28}
29
30#[async_trait]
31impl CliRunStore for InMemoryRunStore {
32 async fn put(&self, result: &CliResult) -> Result<(), HarnessError> {
33 self.inner.insert(result.run_id.clone(), result.clone());
34 Ok(())
35 }
36 async fn get(&self, id: &CliRunId) -> Result<Option<CliResult>, HarnessError> {
37 Ok(self.inner.get(id).map(|r| r.clone()))
38 }
39 async fn list(&self, limit: usize) -> Result<Vec<CliResult>, HarnessError> {
40 let mut all: Vec<CliResult> = self.inner.iter().map(|kv| kv.value().clone()).collect();
41 all.sort_by(|a, b| b.started_at.cmp(&a.started_at));
42 all.truncate(limit);
43 Ok(all)
44 }
45}