use std::path::PathBuf;
use std::sync::Arc;
use crate::engine::db_ops::{DeltaType, UblxDbCategory};
use crate::integrations::{ZahirFT, file_type_from_metadata_name};
use super::TuiRow;
#[derive(Debug, Clone)]
pub struct ViewerDiskContentCache {
pub rel_path: String,
pub category: String,
pub file_len: u64,
pub modified: Option<std::time::SystemTime>,
pub viewer_str: Option<String>,
pub embedded_cover_raster: Option<Vec<u8>>,
pub viewer_can_open: bool,
}
impl ViewerDiskContentCache {
#[must_use]
pub fn matches(&self, path: &str, category: &str, meta: &std::fs::Metadata) -> bool {
self.rel_path == path
&& self.category == category
&& self.file_len == meta.len()
&& self.modified == meta.modified().ok()
}
}
#[derive(Default)]
pub struct RightPaneAsync {
pub generation: u64,
pub last_spawn_path: String,
pub displayed: RightPaneContent,
pub rx: Option<tokio::sync::mpsc::UnboundedReceiver<RightPaneAsyncReady>>,
}
pub struct SectionedPreview {
pub templates: String,
pub metadata: Option<String>,
pub writing: Option<String>,
}
#[derive(Clone)]
pub enum ViewContents {
SnapshotIndices(Vec<usize>),
DeltaRows(Vec<TuiRow>),
}
pub struct ViewData {
pub filtered_categories: Vec<String>,
pub contents: ViewContents,
pub category_list_len: usize,
pub content_len: usize,
}
impl ViewData {
#[must_use]
pub fn row_at<'a>(&'a self, i: usize, all_rows: Option<&'a [TuiRow]>) -> Option<&'a TuiRow> {
match &self.contents {
ViewContents::SnapshotIndices(indices) => indices
.get(i)
.and_then(|&pos| all_rows.and_then(|r| r.get(pos))),
ViewContents::DeltaRows(rows) => rows.get(i),
}
}
#[must_use]
pub fn iter_contents<'a>(
&'a self,
all_rows: Option<&'a [TuiRow]>,
) -> Box<dyn Iterator<Item = &'a TuiRow> + 'a> {
match &self.contents {
ViewContents::SnapshotIndices(indices) => {
let iter = indices
.iter()
.filter_map(move |&pos| all_rows.and_then(|r| r.get(pos)));
Box::new(iter)
}
ViewContents::DeltaRows(rows) => Box::new(rows.iter()),
}
}
}
pub type DeltaRow = (i64, String);
pub struct DeltaViewData {
pub overview_text: String,
pub added_rows: Vec<DeltaRow>,
pub mod_rows: Vec<DeltaRow>,
pub removed_rows: Vec<DeltaRow>,
}
impl DeltaViewData {
#[must_use]
pub fn rows_by_index(&self, idx: usize) -> &[DeltaRow] {
match DeltaType::from_index(idx) {
DeltaType::Added => &self.added_rows,
DeltaType::Mod => &self.mod_rows,
DeltaType::Removed => &self.removed_rows,
}
}
}
#[derive(Debug)]
pub struct RightPaneAsyncReady {
pub generation: u64,
pub path: String,
pub content: RightPaneContent,
pub disk_cache: Option<ViewerDiskContentCache>,
}
#[derive(Clone, Debug, Default)]
pub struct SnapshotEntryMeta {
pub path: Option<String>,
pub category: Option<String>,
pub size: Option<u64>,
pub mtime_ns: Option<i64>,
pub has_zahir_json: bool,
}
#[derive(Clone, Debug, Default)]
pub struct RightPaneContentDerived {
pub abs_path: Option<PathBuf>,
pub can_open: bool,
pub offer_enhance_zahir: bool,
pub offer_enhance_directory_policy: bool,
pub embedded_cover_raster: Option<Vec<u8>>,
}
#[derive(Default, Clone, Debug)]
pub struct RightPaneContent {
pub templates: String,
pub metadata: Option<String>,
pub writing: Option<String>,
pub viewer: Option<Arc<str>>,
pub viewer_directory_policy_line: Option<String>,
pub snap_meta: SnapshotEntryMeta,
pub derived: RightPaneContentDerived,
}
impl RightPaneContent {
#[must_use]
pub fn empty() -> Self {
Self::default()
}
#[must_use]
pub fn zahir_file_type(&self) -> Option<ZahirFT> {
file_type_from_metadata_name(self.snap_meta.category.as_deref().unwrap_or(""))
}
#[must_use]
pub fn ublx_db_category(&self) -> UblxDbCategory {
UblxDbCategory::from_snapshot_category(self.snap_meta.category.as_deref().unwrap_or(""))
}
}