use crate::types::TaskId;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Mutex;
use thiserror::Error;
pub mod inmemory;
pub mod sqlite;
pub use inmemory::InMemoryTaskStore;
pub use sqlite::SqliteTaskStore;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskRecordStatus {
Pending,
Running,
Done,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskRecord {
pub id: TaskId,
pub goal: String,
pub blueprint_ref: serde_json::Value,
pub input_ctx: serde_json::Value,
pub status: TaskRecordStatus,
pub created_at: u64,
pub updated_at: u64,
}
#[derive(Debug, Error)]
pub enum TaskStoreError {
#[error("task not found: {0}")]
NotFound(TaskId),
#[error("task already exists: {0}")]
Duplicate(TaskId),
#[error("other: {0}")]
Other(String),
}
#[async_trait]
pub trait TaskStore: Send + Sync {
fn name(&self) -> &str;
async fn create(&self, record: TaskRecord) -> Result<(), TaskStoreError>;
async fn get(&self, id: &TaskId) -> Result<TaskRecord, TaskStoreError>;
async fn list(&self) -> Result<Vec<TaskRecord>, TaskStoreError>;
async fn update_status(
&self,
id: &TaskId,
status: TaskRecordStatus,
) -> Result<(), TaskStoreError>;
}
#[derive(Default)]
pub(crate) struct Inner {
pub(crate) order: Vec<TaskId>,
pub(crate) records: HashMap<TaskId, TaskRecord>,
}
pub(crate) type SharedInner = Mutex<Inner>;