use std::collections::{BTreeMap, HashMap};
use std::sync::OnceLock;
use serde::{Deserialize, Serialize};
use crate::debug_response::NetStructure;
pub const CURRENT_VERSION: u32 = 2;
pub const MIN_SUPPORTED_VERSION: u32 = 1;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionArchiveV1 {
pub version: u32,
pub session_id: String,
pub net_name: String,
pub dot_diagram: String,
pub start_time: String,
pub event_count: usize,
pub structure: NetStructure,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionArchiveV2 {
pub version: u32,
pub session_id: String,
pub net_name: String,
pub dot_diagram: String,
pub start_time: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub end_time: Option<String>,
pub event_count: usize,
#[serde(default)]
pub tags: HashMap<String, String>,
pub metadata: SessionMetadata,
pub structure: NetStructure,
}
#[derive(Debug, Clone)]
pub enum SessionArchive {
V1(SessionArchiveV1),
V2(SessionArchiveV2),
}
impl SessionArchive {
pub fn version(&self) -> u32 {
match self {
Self::V1(a) => a.version,
Self::V2(a) => a.version,
}
}
pub fn session_id(&self) -> &str {
match self {
Self::V1(a) => &a.session_id,
Self::V2(a) => &a.session_id,
}
}
pub fn net_name(&self) -> &str {
match self {
Self::V1(a) => &a.net_name,
Self::V2(a) => &a.net_name,
}
}
pub fn dot_diagram(&self) -> &str {
match self {
Self::V1(a) => &a.dot_diagram,
Self::V2(a) => &a.dot_diagram,
}
}
pub fn start_time(&self) -> &str {
match self {
Self::V1(a) => &a.start_time,
Self::V2(a) => &a.start_time,
}
}
pub fn event_count(&self) -> usize {
match self {
Self::V1(a) => a.event_count,
Self::V2(a) => a.event_count,
}
}
pub fn structure(&self) -> &NetStructure {
match self {
Self::V1(a) => &a.structure,
Self::V2(a) => &a.structure,
}
}
pub fn end_time(&self) -> Option<&str> {
match self {
Self::V1(_) => None,
Self::V2(a) => a.end_time.as_deref(),
}
}
pub fn tags(&self) -> &HashMap<String, String> {
static EMPTY: OnceLock<HashMap<String, String>> = OnceLock::new();
match self {
Self::V1(_) => EMPTY.get_or_init(HashMap::new),
Self::V2(a) => &a.tags,
}
}
pub fn metadata(&self) -> Option<&SessionMetadata> {
match self {
Self::V1(_) => None,
Self::V2(a) => Some(&a.metadata),
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionMetadata {
#[serde(default)]
pub event_type_histogram: BTreeMap<String, u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub first_event_time: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub last_event_time: Option<String>,
#[serde(default)]
pub has_errors: bool,
}
impl SessionMetadata {
pub fn empty() -> Self {
Self::default()
}
}