sabiql 1.11.0

A fast, driver-less TUI for browsing and editing PostgreSQL databases
Documentation
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct JsonTree {
    lines: Vec<TreeLine>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TreeLine {
    pub depth: usize,
    pub key: Option<String>,
    pub value: TreeValue,
    pub collapsed: bool,
    pub line_type: LineType,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LineType {
    ObjectOpen,
    ObjectClose,
    ArrayOpen,
    ArrayClose,
    KeyValue,
    ArrayItem,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TreeValue {
    Null,
    Bool(bool),
    Number(String),
    String(String),
    ObjectOpen { child_count: usize },
    ArrayOpen { child_count: usize },
    Closing,
}

impl JsonTree {
    pub fn new(lines: Vec<TreeLine>) -> Self {
        Self { lines }
    }

    pub fn lines(&self) -> &[TreeLine] {
        &self.lines
    }

    pub fn lines_mut(&mut self) -> &mut [TreeLine] {
        &mut self.lines
    }

    pub fn line_count(&self) -> usize {
        self.lines.len()
    }

    pub fn is_empty(&self) -> bool {
        self.lines.is_empty()
    }

    pub fn toggle_fold(&mut self, line_idx: usize) -> bool {
        if let Some(line) = self.lines.get_mut(line_idx)
            && matches!(line.line_type, LineType::ObjectOpen | LineType::ArrayOpen)
        {
            line.collapsed = !line.collapsed;
            return true;
        }
        false
    }

    pub fn fold_all(&mut self) {
        for line in &mut self.lines {
            if matches!(line.line_type, LineType::ObjectOpen | LineType::ArrayOpen) {
                line.collapsed = true;
            }
        }
    }

    pub fn unfold_all(&mut self) {
        for line in &mut self.lines {
            if matches!(line.line_type, LineType::ObjectOpen | LineType::ArrayOpen) {
                line.collapsed = false;
            }
        }
    }
}

impl TreeLine {
    pub fn is_collapsible(&self) -> bool {
        matches!(self.line_type, LineType::ObjectOpen | LineType::ArrayOpen)
    }
}