use serde::{Deserialize, Serialize};
use super::HIVE_DEFAULT_URL;
use crate::UtcTimestamp;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusInstanceV1 {
pub id: String,
pub label: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusOrgV1 {
pub name: String,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusDraftsV1 {
pub queued: u32,
pub refused: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusFilterPackV1 {
pub pack_id: String,
pub version: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HiveBusControlActionV1 {
Hold,
Stop,
Veto,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusBusControlV1 {
pub target_agent: Option<String>,
pub action: HiveBusControlActionV1,
pub target_ref: Option<String>,
pub reason: String,
pub issued_by: String,
pub since: UtcTimestamp,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HiveBusControlsInactiveV1 {
NotEnrolled,
LeaseLapsed,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveCliStatusV1 {
pub available: bool,
pub connected: bool,
pub instance: Option<HiveStatusInstanceV1>,
pub org: Option<HiveStatusOrgV1>,
pub last_seen: Option<UtcTimestamp>,
pub url: String,
#[serde(default)]
pub drafts: HiveStatusDraftsV1,
#[serde(default)]
pub filter_packs: Vec<HiveStatusFilterPackV1>,
#[serde(default)]
pub policy_refusal: Option<String>,
#[serde(default)]
pub web_url: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub bus_controls: Vec<HiveStatusBusControlV1>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub bus_controls_inactive: Option<HiveBusControlsInactiveV1>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub metrics_v2: Option<HiveStatusMetricsV2>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HiveStatusMetricsV2 {
pub sharing: super::metrics_v2::SharingStateV2,
pub last_sent_at: Option<String>,
pub buffered_buckets: u64,
pub dropped_buckets: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub released: Option<bool>,
}
impl HiveCliStatusV1 {
pub fn not_connected(url: Option<&str>) -> Self {
Self {
available: true,
connected: false,
instance: None,
org: None,
last_seen: None,
url: url.unwrap_or(HIVE_DEFAULT_URL).to_string(),
drafts: HiveStatusDraftsV1::default(),
filter_packs: Vec::new(),
policy_refusal: None,
web_url: Some(url.unwrap_or(HIVE_DEFAULT_URL).to_string()),
bus_controls: Vec::new(),
bus_controls_inactive: None,
metrics_v2: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn not_connected_prints_nulls() {
assert_eq!(
serde_json::to_string(&HiveCliStatusV1::not_connected(None)).unwrap(),
r#"{"available":true,"connected":false,"instance":null,"org":null,"last_seen":null,"url":"https://hive.leanctx.com","drafts":{"queued":0,"refused":0},"filter_packs":[],"policy_refusal":null,"web_url":"https://hive.leanctx.com"}"#
);
}
#[test]
fn bus_controls_appear_only_when_present() {
let mut status = HiveCliStatusV1::not_connected(None);
let quiet = serde_json::to_string(&status).unwrap();
assert!(!quiet.contains("bus_controls"));
status.bus_controls_inactive = Some(HiveBusControlsInactiveV1::LeaseLapsed);
assert!(
serde_json::to_string(&status)
.unwrap()
.contains(r#""bus_controls_inactive":"lease_lapsed""#)
);
}
#[test]
fn a_1_0_status_still_reads() {
let old = r#"{"available":true,"connected":false,"instance":null,"org":null,"last_seen":null,"url":"https://hive.leanctx.com"}"#;
let status: HiveCliStatusV1 = serde_json::from_str(old).unwrap();
assert_eq!(
status,
HiveCliStatusV1 {
web_url: None,
..HiveCliStatusV1::not_connected(None)
}
);
}
}