fmtview 0.2.1

Fast terminal formatter and viewer for JSON, JSONL, XML-compatible markup, and formatted diffs
Documentation
use anyhow::Result;

use crate::{
    format::FormatOptions,
    input::InputSource,
    preview::{self, PreviewPlan},
};

use super::{
    DiffModel, LazyRecordDiff,
    external::{format_diff_inputs, run_external_diff_view_model},
};

pub(crate) enum DiffView {
    Eager(DiffModel),
    Lazy(Box<LazyRecordDiff>),
}

impl DiffView {
    pub(crate) fn model(&self) -> &DiffModel {
        match self {
            Self::Eager(model) => model,
            Self::Lazy(diff) => diff.model(),
        }
    }

    pub(crate) fn preload(
        &mut self,
        max_records: usize,
        budget: std::time::Duration,
    ) -> Result<bool> {
        match self {
            Self::Eager(_) => Ok(false),
            Self::Lazy(diff) => diff.preload(max_records, budget),
        }
    }

    pub(crate) fn is_complete(&self) -> bool {
        match self {
            Self::Eager(_) => true,
            Self::Lazy(diff) => diff.is_complete(),
        }
    }
}

pub(crate) fn diff_view(
    left: &InputSource,
    right: &InputSource,
    options: &FormatOptions,
) -> Result<DiffView> {
    if should_use_lazy_record_diff(left, right, options)? {
        return Ok(DiffView::Lazy(Box::new(LazyRecordDiff::new(
            left, right, *options,
        )?)));
    }

    let formatted = format_diff_inputs(left, right, options)?;
    Ok(DiffView::Eager(run_external_diff_view_model(
        left,
        right,
        &formatted.left,
        &formatted.right,
    )?))
}

fn should_use_lazy_record_diff(
    left: &InputSource,
    right: &InputSource,
    options: &FormatOptions,
) -> Result<bool> {
    Ok(
        preview::preview_plan(left, options)? == PreviewPlan::LazyRecords
            && preview::preview_plan(right, options)? == PreviewPlan::LazyRecords,
    )
}