Skip to main content

gglib_core/events/
app.rs

1//! Application-level events (model lifecycle).
2
3use serde::{Deserialize, Serialize};
4
5use super::AppEvent;
6
7/// Summary of a model for event payloads.
8///
9/// This is a lightweight representation for events — not the full `Model`.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11#[cfg_attr(feature = "ts-bindings", derive(ts_rs::TS), ts(export))]
12#[serde(rename_all = "camelCase")]
13pub struct ModelSummary {
14    /// Database ID of the model.
15    #[cfg_attr(feature = "ts-bindings", ts(type = "number"))]
16    pub id: i64,
17    /// Human-readable model name.
18    pub name: String,
19    /// File path to the model.
20    pub file_path: String,
21    /// Model architecture (e.g., "llama").
22    #[cfg_attr(feature = "ts-bindings", ts(optional))]
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub architecture: Option<String>,
25    /// Quantization type (e.g., "`Q4_0`").
26    #[cfg_attr(feature = "ts-bindings", ts(optional))]
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub quantization: Option<String>,
29}
30
31impl ModelSummary {
32    /// Create a new model summary.
33    pub fn new(
34        id: i64,
35        name: impl Into<String>,
36        file_path: impl Into<String>,
37        architecture: Option<String>,
38        quantization: Option<String>,
39    ) -> Self {
40        Self {
41            id,
42            name: name.into(),
43            file_path: file_path.into(),
44            architecture,
45            quantization,
46        }
47    }
48}
49
50/// Borrow a stored model as the lightweight summary events carry.
51///
52/// Every emit site wants the same five fields off a [`Model`](crate::domain::Model)
53/// it already has,
54/// so the mapping lives here rather than being spelled out per call site.
55impl From<&crate::domain::Model> for ModelSummary {
56    fn from(model: &crate::domain::Model) -> Self {
57        Self {
58            id: model.id,
59            name: model.name.clone(),
60            file_path: model.file_path.to_string_lossy().into_owned(),
61            architecture: model.architecture.clone(),
62            quantization: model.quantization.clone(),
63        }
64    }
65}
66
67impl AppEvent {
68    /// Create a model added event.
69    pub const fn model_added(model: ModelSummary) -> Self {
70        Self::ModelAdded { model }
71    }
72
73    /// Create a model removed event.
74    pub const fn model_removed(model_id: i64) -> Self {
75        Self::ModelRemoved { model_id }
76    }
77
78    /// Create a model updated event.
79    pub const fn model_updated(model: ModelSummary) -> Self {
80        Self::ModelUpdated { model }
81    }
82}