systemprompt-models 0.53.0

Foundation data models for systemprompt.io AI governance infrastructure. Shared DTOs, config, and domain types consumed by every layer of the MCP governance pipeline.
Documentation
//! Managed-service record decoded from a `services` row.
//!
//! Copyright (c) systemprompt.io — Business Source License 1.1.
//! See <https://systemprompt.io> for licensing details.

use serde::{Deserialize, Serialize};

use crate::errors::RowParseError;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceRecord {
    pub name: String,
    pub module_name: String,
    pub status: String,
    pub pid: Option<i32>,
    pub port: i32,
}

impl ServiceRecord {
    pub fn from_json_row(
        // JSON: `services` row decoded from a dynamic query result.
        row: &std::collections::HashMap<String, serde_json::Value>,
    ) -> Result<Self, RowParseError> {
        let name = row
            .get("name")
            .and_then(|v| v.as_str())
            .ok_or(RowParseError::Missing("name"))?
            .to_owned();

        let module_name = row
            .get("module_name")
            .and_then(|v| v.as_str())
            .ok_or(RowParseError::Missing("module_name"))?
            .to_owned();

        let status = row
            .get("status")
            .and_then(|v| v.as_str())
            .ok_or(RowParseError::Missing("status"))?
            .to_owned();

        let pid = row
            .get("pid")
            .and_then(serde_json::Value::as_i64)
            .and_then(|i| i32::try_from(i).ok());

        let port = row
            .get("port")
            .and_then(serde_json::Value::as_i64)
            .ok_or(RowParseError::Missing("port"))
            .and_then(|i| i32::try_from(i).map_err(|_e| RowParseError::OutOfRange("port")))?;

        Ok(Self {
            name,
            module_name,
            status,
            pid,
            port,
        })
    }
}