use serde::{Deserialize, Serialize};
use std::path::PathBuf;
pub const SESSION_FORMAT_VERSION: u8 = 1;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionTab {
pub title: String,
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionWindow {
pub title: String,
#[serde(default)]
pub tabs: Vec<SessionTab>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SafariSession {
#[serde(default = "default_format_version")]
pub format_version: u8,
pub captured_at: String,
#[serde(default)]
pub windows: Vec<SessionWindow>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionSummary {
pub path: PathBuf,
pub file_name: String,
pub captured_at: String,
pub window_count: usize,
pub tab_count: usize,
}
const fn default_format_version() -> u8 {
SESSION_FORMAT_VERSION
}
impl SafariSession {
pub fn new(captured_at: String, windows: Vec<SessionWindow>) -> Self {
Self {
format_version: SESSION_FORMAT_VERSION,
captured_at,
windows,
}
}
pub fn window_count(&self) -> usize {
self.windows.len()
}
pub fn tab_count(&self) -> usize {
self.windows.iter().map(|window| window.tabs.len()).sum()
}
pub fn is_empty(&self) -> bool {
self.windows.is_empty()
}
}
impl SessionSummary {
pub fn from_session(path: PathBuf, session: &SafariSession) -> Self {
let file_name = path
.file_name()
.and_then(|name| name.to_str())
.unwrap_or("unknown.json")
.to_string();
Self {
path,
file_name,
captured_at: session.captured_at.clone(),
window_count: session.window_count(),
tab_count: session.tab_count(),
}
}
}