systemprompt_models/repository/
service.rs1use anyhow::{Result, anyhow};
2use async_trait::async_trait;
3use serde::{Deserialize, Serialize};
4use systemprompt_traits::RepositoryError;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ServiceRecord {
8 pub name: String,
9 pub module_name: String,
10 pub status: String,
11 pub pid: Option<i32>,
12 pub port: i32,
13}
14
15impl ServiceRecord {
16 pub fn from_json_row(
17 row: &std::collections::HashMap<String, serde_json::Value>,
18 ) -> Result<Self> {
19 let name = row
20 .get("name")
21 .and_then(|v| v.as_str())
22 .ok_or_else(|| anyhow!("Missing name"))?
23 .to_string();
24
25 let module_name = row
26 .get("module_name")
27 .and_then(|v| v.as_str())
28 .ok_or_else(|| anyhow!("Missing module_name"))?
29 .to_string();
30
31 let status = row
32 .get("status")
33 .and_then(|v| v.as_str())
34 .ok_or_else(|| anyhow!("Missing status"))?
35 .to_string();
36
37 let pid = row
38 .get("pid")
39 .and_then(serde_json::Value::as_i64)
40 .and_then(|i| i32::try_from(i).ok());
41
42 let port = row
43 .get("port")
44 .and_then(serde_json::Value::as_i64)
45 .ok_or_else(|| anyhow!("Missing port"))
46 .and_then(|i| i32::try_from(i).map_err(|_| anyhow!("Port out of range")))?;
47
48 Ok(Self {
49 name,
50 module_name,
51 status,
52 pid,
53 port,
54 })
55 }
56}
57
58#[async_trait]
59pub trait ServiceLifecycle: Send + Sync {
60 async fn get_running_services(&self) -> Result<Vec<ServiceRecord>, RepositoryError>;
61 async fn mark_crashed(&self, service_name: &str) -> Result<(), RepositoryError>;
62 async fn update_status(&self, service_name: &str, status: &str) -> Result<(), RepositoryError>;
63}