use chrono::{DateTime, Utc};
use futures::Stream;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt;
use std::pin::Pin;
use crate::error::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Protocol {
JsonRpc,
RawCommands,
}
impl fmt::Display for Protocol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Protocol::JsonRpc => write!(f, "JSON-RPC"),
Protocol::RawCommands => write!(f, "Raw Commands"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ServerCapabilities {
pub protocol: Protocol,
pub supports_create: bool,
pub supports_delete: bool,
pub supports_get_config: bool,
pub supports_stats: bool,
pub supports_log_streaming: bool,
pub supports_http_server: bool,
}
impl ServerCapabilities {
pub fn full() -> Self {
Self {
protocol: Protocol::JsonRpc,
supports_create: true,
supports_delete: true,
supports_get_config: true,
supports_stats: true,
supports_log_streaming: true,
supports_http_server: true,
}
}
pub fn legacy() -> Self {
Self {
protocol: Protocol::RawCommands,
supports_create: false,
supports_delete: false,
supports_get_config: false,
supports_stats: false,
supports_log_streaming: true, supports_http_server: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "PascalCase")]
pub enum ServiceState {
Unknown,
Blocked,
Spawned,
Running,
Success,
Error,
TestFailure,
}
impl fmt::Display for ServiceState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ServiceState::Unknown => write!(f, "Unknown"),
ServiceState::Blocked => write!(f, "Blocked"),
ServiceState::Spawned => write!(f, "Spawned"),
ServiceState::Running => write!(f, "Running"),
ServiceState::Success => write!(f, "Success"),
ServiceState::Error => write!(f, "Error"),
ServiceState::TestFailure => write!(f, "TestFailure"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "PascalCase")]
pub enum ServiceTarget {
Up,
Down,
}
impl fmt::Display for ServiceTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ServiceTarget::Up => write!(f, "Up"),
ServiceTarget::Down => write!(f, "Down"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceStatus {
pub name: String,
pub pid: u32,
pub state: ServiceState,
pub target: ServiceTarget,
pub after: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LogEntry {
pub timestamp: DateTime<Utc>,
pub service: String,
pub message: String,
}
pub struct LogStream {
pub(crate) inner: Pin<Box<dyn Stream<Item = Result<LogEntry>> + Send>>,
}
impl Stream for LogStream {
type Item = Result<LogEntry>;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
Pin::new(&mut self.inner).poll_next(cx)
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct Response {
pub state: ResponseState,
pub body: serde_json::Value,
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub(crate) enum ResponseState {
Ok,
Error,
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct JsonRpcRequest {
pub jsonrpc: String,
pub method: String,
pub params: serde_json::Value,
pub id: u64,
}
impl JsonRpcRequest {
pub fn new(method: &str, params: serde_json::Value, id: u64) -> Self {
Self {
jsonrpc: "2.0".to_string(),
method: method.to_string(),
params,
id,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct JsonRpcResponse {
#[allow(dead_code)]
pub jsonrpc: String,
#[allow(dead_code)]
pub id: Option<u64>,
pub result: Option<serde_json::Value>,
pub error: Option<JsonRpcError>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct JsonRpcError {
pub code: i32,
pub message: String,
pub data: Option<serde_json::Value>,
}