1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::{json, Value};
4use uuid::Uuid;
5
6pub type RendererId = Uuid;
7
8pub use crate::protocol::{
10 InstanceId, InstanceSnapshot, RenderTarget, RendererMessage, ServerMessage,
11};
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Graphic {
15 pub id: String,
16 pub name: String,
17 pub version: Option<String>,
18 pub description: Option<String>,
19 pub manifest: Value,
20 pub storage_path: String,
21 pub uploaded_at: String,
22}
23
24impl Graphic {
25 pub fn list_info(&self) -> Value {
28 let mut info = json!({
29 "id": self.id,
30 "name": self.name,
31 });
32 if let Some(description) = &self.description {
33 info["description"] = json!(description);
34 }
35 if let Some(thumbnails) = self.manifest.get("thumbnails") {
36 info["thumbnails"] = thumbnails.clone();
37 }
38 info
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct RendererMetrics {
48 pub pending_requests: usize,
49 pub messages_sent: u64,
50 pub messages_received: u64,
51 pub uptime_seconds: u64,
52}
53
54#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
59#[serde(rename_all = "camelCase")]
60pub enum InstanceState {
61 Loaded,
62 Playing,
63 Stopped,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct GraphicInstance {
68 pub instance_id: InstanceId,
69 pub graphic_id: String,
70 pub data: Option<Value>,
71 pub loaded_at: DateTime<Utc>,
72 pub state: InstanceState,
73 pub current_step: Option<f64>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct RendererInfo {
82 pub id: RendererId,
83 pub name: String,
84 pub connected_at: DateTime<Utc>,
85 pub render_target: RenderTarget,
86 pub render_target_schema: Option<Value>,
90 pub instances: Vec<GraphicInstance>,
91 #[serde(skip_serializing_if = "Option::is_none")]
94 pub metrics: Option<RendererMetrics>,
95}