1use chrono::{DateTime, Utc};
2use futures::Stream;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fmt;
6use std::pin::Pin;
7
8use crate::error::Result;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum Protocol {
13 JsonRpc,
15 RawCommands,
17}
18
19impl fmt::Display for Protocol {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match self {
22 Protocol::JsonRpc => write!(f, "JSON-RPC"),
23 Protocol::RawCommands => write!(f, "Raw Commands"),
24 }
25 }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct ServerCapabilities {
31 pub protocol: Protocol,
33 pub supports_create: bool,
35 pub supports_delete: bool,
37 pub supports_get_config: bool,
39 pub supports_stats: bool,
41 pub supports_log_streaming: bool,
43 pub supports_http_server: bool,
45}
46
47impl ServerCapabilities {
48 pub fn full() -> Self {
50 Self {
51 protocol: Protocol::JsonRpc,
52 supports_create: true,
53 supports_delete: true,
54 supports_get_config: true,
55 supports_stats: true,
56 supports_log_streaming: true,
57 supports_http_server: true,
58 }
59 }
60
61 pub fn legacy() -> Self {
63 Self {
64 protocol: Protocol::RawCommands,
65 supports_create: false,
66 supports_delete: false,
67 supports_get_config: false,
68 supports_stats: false,
69 supports_log_streaming: true, supports_http_server: false,
71 }
72 }
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
77#[serde(rename_all = "PascalCase")]
78pub enum ServiceState {
79 Unknown,
81 Blocked,
83 Spawned,
85 Running,
87 Success,
89 Error,
91 TestFailure,
93}
94
95impl fmt::Display for ServiceState {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 match self {
98 ServiceState::Unknown => write!(f, "Unknown"),
99 ServiceState::Blocked => write!(f, "Blocked"),
100 ServiceState::Spawned => write!(f, "Spawned"),
101 ServiceState::Running => write!(f, "Running"),
102 ServiceState::Success => write!(f, "Success"),
103 ServiceState::Error => write!(f, "Error"),
104 ServiceState::TestFailure => write!(f, "TestFailure"),
105 }
106 }
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
111#[serde(rename_all = "PascalCase")]
112pub enum ServiceTarget {
113 Up,
115 Down,
117}
118
119impl fmt::Display for ServiceTarget {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 match self {
122 ServiceTarget::Up => write!(f, "Up"),
123 ServiceTarget::Down => write!(f, "Down"),
124 }
125 }
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct ServiceStatus {
131 pub name: String,
133 pub pid: u32,
135 pub state: ServiceState,
137 pub target: ServiceTarget,
139 pub after: HashMap<String, String>,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct LogEntry {
146 pub timestamp: DateTime<Utc>,
148 pub service: String,
150 pub message: String,
152}
153
154pub struct LogStream {
156 pub(crate) inner: Pin<Box<dyn Stream<Item = Result<LogEntry>> + Send>>,
158}
159
160impl Stream for LogStream {
161 type Item = Result<LogEntry>;
162
163 fn poll_next(
164 mut self: Pin<&mut Self>,
165 cx: &mut std::task::Context<'_>,
166 ) -> std::task::Poll<Option<Self::Item>> {
167 Pin::new(&mut self.inner).poll_next(cx)
168 }
169}
170
171#[derive(Debug, Clone, Deserialize)]
173pub(crate) struct Response {
174 pub state: ResponseState,
176 pub body: serde_json::Value,
178}
179
180#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
182#[serde(rename_all = "lowercase")]
183pub(crate) enum ResponseState {
184 Ok,
186 Error,
188}
189
190#[derive(Debug, Clone, Serialize)]
192pub(crate) struct JsonRpcRequest {
193 pub jsonrpc: String,
195 pub method: String,
197 pub params: serde_json::Value,
199 pub id: u64,
201}
202
203impl JsonRpcRequest {
204 pub fn new(method: &str, params: serde_json::Value, id: u64) -> Self {
206 Self {
207 jsonrpc: "2.0".to_string(),
208 method: method.to_string(),
209 params,
210 id,
211 }
212 }
213}
214
215#[derive(Debug, Clone, Deserialize)]
217pub(crate) struct JsonRpcResponse {
218 #[allow(dead_code)]
220 pub jsonrpc: String,
221 #[allow(dead_code)]
223 pub id: Option<u64>,
224 pub result: Option<serde_json::Value>,
226 pub error: Option<JsonRpcError>,
228}
229
230#[derive(Debug, Clone, Deserialize)]
232pub(crate) struct JsonRpcError {
233 pub code: i32,
235 pub message: String,
237 pub data: Option<serde_json::Value>,
239}