speakers_core/
protocol.rs1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5use crate::model::ModelVariant;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(tag = "kind", rename_all = "snake_case")]
9pub enum VoiceSelection {
10 Preset { name: String },
11 Profile { name: String },
12}
13
14impl VoiceSelection {
15 pub fn preset(name: impl Into<String>) -> Self {
16 Self::Preset { name: name.into() }
17 }
18
19 pub fn profile(name: impl Into<String>) -> Self {
20 Self::Profile { name: name.into() }
21 }
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(tag = "type", rename_all = "snake_case")]
26pub enum DaemonRequest {
27 Health,
28 Shutdown,
29 Synthesize {
30 text: String,
31 language: String,
32 output: PathBuf,
33 voice: VoiceSelection,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 rate: Option<i32>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pitch: Option<i32>,
38 },
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct HealthData {
43 pub pid: u32,
44 pub model: ModelVariant,
45 pub device: String,
46 pub socket: PathBuf,
47 pub uptime_secs: u64,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct SynthesisData {
52 pub output: PathBuf,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56#[serde(tag = "kind", content = "payload", rename_all = "snake_case")]
57pub enum ResponseData {
58 Ack,
59 Health(HealthData),
60 Synthesis(SynthesisData),
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct DaemonResponse {
65 pub ok: bool,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub error_code: Option<String>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub error_message: Option<String>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub error_details: Option<Vec<String>>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub data: Option<ResponseData>,
74}
75
76impl DaemonResponse {
77 pub fn ok(data: Option<ResponseData>) -> Self {
78 Self {
79 ok: true,
80 error_code: None,
81 error_message: None,
82 error_details: None,
83 data,
84 }
85 }
86
87 pub fn error(code: impl Into<String>, message: impl Into<String>) -> Self {
88 Self::error_with_details(code, message, Vec::<String>::new())
89 }
90
91 pub fn error_with_details(
92 code: impl Into<String>,
93 message: impl Into<String>,
94 details: Vec<String>,
95 ) -> Self {
96 Self {
97 ok: false,
98 error_code: Some(code.into()),
99 error_message: Some(message.into()),
100 error_details: (!details.is_empty()).then_some(details),
101 data: None,
102 }
103 }
104}