logisheets_controller 0.7.0

the core of LogiSheets
Documentation
use logisheets_base::{
    errors::BasicError, index_fetcher::IndexFetcherTrait, name_fetcher::NameFetcherTrait, ColId,
    Cube, RowId, SheetId, TextId,
};
use logisheets_workbook::workbook::Wb;

use crate::{
    cube_manager::CubeManager,
    ext_book_manager::ExtBooksManager,
    ext_ref_manager::ExtRefManager,
    file_saver::workbook::save_workbook,
    formula_manager::FormulaManager,
    id_manager::{FuncIdManager, NameIdManager, SheetIdManager, TextIdManager},
    navigator::Navigator,
    range_manager::RangeManager,
    workbook::sheet_pos_manager::SheetPosManager,
    Controller,
};

pub use self::error::SaveError;
type Result<T> = std::result::Result<T, BasicError>;

mod error;
mod external_links;
mod sst;
mod styles;
mod utils;
mod workbook;
mod worksheet;

pub fn save_file(controller: &Controller) -> std::result::Result<Wb, SaveError> {
    let func_manager = &controller.status.func_id_manager;
    let external_links_manager = &controller.status.external_links_manager;
    let text_id_manager = &controller.status.text_id_manager;
    let name_id_manager = &controller.status.name_id_manager;
    let formula_manager = &controller.status.formula_manager;
    let range_manager = &controller.status.range_manager;
    let cube_manager = &controller.status.cube_manager;
    let ext_ref_manager = &controller.status.ext_ref_manager;

    let data_container = &controller.status.container;
    let attachment_manager = &controller.status.cell_attachment_manager;
    let sheet_pos_manager = &controller.status.sheet_pos_manager;
    let sheet_id_manager = &controller.status.sheet_id_manager;
    let style_manager = &controller.status.style_manager;
    let ext_book_manager = &controller.status.external_links_manager;
    let theme_manager = &controller.settings.theme;

    let settings = &controller.settings;

    let mut navigator_replication = controller.status.navigator.clone();
    let mut saver = Saver {
        part_count: 0,
        external_count: 0,
        func_manager,
        range_manager,
        cube_manager,
        ext_ref_manager,
        sheet_id_manager,
        external_links_manager,
        text_id_manager,
        name_id_manager,
        navigator: &mut navigator_replication,
        formula_manager,
        sheet_pos_manager,
    };

    save_workbook(
        data_container,
        formula_manager,
        attachment_manager,
        sheet_pos_manager,
        sheet_id_manager,
        style_manager,
        ext_book_manager,
        theme_manager,
        text_id_manager,
        settings,
        &mut saver,
    )
}

pub trait SaverTrait: IndexFetcherTrait + NameFetcherTrait {
    fn fetch_part_id(&mut self) -> String;

    fn fetch_row_id(&mut self, sheet_id: SheetId, idx: usize) -> RowId;
}

pub struct Saver<'a> {
    pub part_count: u32,
    pub external_count: u32,

    pub func_manager: &'a FuncIdManager,
    pub sheet_id_manager: &'a SheetIdManager,
    pub external_links_manager: &'a ExtBooksManager,
    pub text_id_manager: &'a TextIdManager,
    pub name_id_manager: &'a NameIdManager,
    pub navigator: &'a mut Navigator,
    pub formula_manager: &'a FormulaManager,
    pub range_manager: &'a RangeManager,
    pub cube_manager: &'a CubeManager,
    pub ext_ref_manager: &'a ExtRefManager,
    pub sheet_pos_manager: &'a SheetPosManager,
}

impl<'a> IndexFetcherTrait for Saver<'a> {
    fn fetch_row_index(&self, sheet_id: &SheetId, row_id: &RowId) -> Result<usize> {
        self.navigator.fetch_row_idx(sheet_id, row_id)
    }

    fn fetch_col_index(&self, sheet_id: &SheetId, col_id: &ColId) -> Result<usize> {
        self.navigator.fetch_col_idx(sheet_id, col_id)
    }

    fn fetch_cell_index(
        &self,
        sheet_id: &SheetId,
        cell_id: &logisheets_base::CellId,
    ) -> Result<(usize, usize)> {
        self.navigator.fetch_cell_idx(sheet_id, cell_id)
    }

    fn fetch_sheet_index(&self, sheet_id: &SheetId) -> Result<usize> {
        self.sheet_pos_manager
            .get_sheet_idx(sheet_id)
            .ok_or(BasicError::SheetIdNotFound(*sheet_id))
    }

    fn fetch_normal_cell_index(
        &self,
        sheet_id: &SheetId,
        normal_cell_id: &logisheets_base::NormalCellId,
    ) -> Result<(usize, usize)> {
        self.navigator
            .fetch_normal_cell_idx(sheet_id, normal_cell_id)
    }

    fn fetch_block_cell_index(
        &self,
        sheet: &SheetId,
        block_cell_id: &logisheets_base::BlockCellId,
    ) -> Result<(usize, usize)> {
        self.navigator.fetch_block_cell_idx(sheet, block_cell_id)
    }
}

impl<'a> NameFetcherTrait for Saver<'a> {
    fn fetch_text(&self, text_id: &TextId) -> Result<String> {
        self.text_id_manager
            .get_string(text_id)
            .ok_or(BasicError::TextIdNotFound(*text_id))
    }

    fn fetch_func_name(&self, func_id: &logisheets_base::FuncId) -> Result<String> {
        self.func_manager
            .get_string(func_id)
            .ok_or(BasicError::FuncIdNotFound(*func_id))
    }

    fn fetch_sheet_name(&self, sheet_id: &SheetId) -> Result<String> {
        self.sheet_id_manager
            .get_string(sheet_id)
            .ok_or(BasicError::SheetIdNotFound(*sheet_id))
    }

    fn fetch_book_name(&self, book_id: &logisheets_base::ExtBookId) -> Result<String> {
        self.external_links_manager
            .fetch_book_name(book_id)
            .ok_or_else(|| BasicError::BookIdNotFound(*book_id))
    }

    fn fetch_defined_name(&self, nid: &logisheets_base::NameId) -> Result<String> {
        self.name_id_manager
            .get_string(nid)
            .and_then(|(_, s)| Some(s))
            .ok_or(BasicError::NameNotFound(*nid))
    }

    fn fetch_cell_idx(
        &self,
        sheet_id: &SheetId,
        cell_id: &logisheets_base::CellId,
    ) -> Result<(usize, usize)> {
        self.navigator.fetch_cell_idx(sheet_id, cell_id)
    }

    fn fetch_row_idx(&self, sheet_id: &SheetId, row_id: &RowId) -> Result<usize> {
        self.navigator.fetch_row_idx(sheet_id, row_id)
    }

    fn fetch_col_idx(&self, sheet_id: &SheetId, col_id: &ColId) -> Result<usize> {
        self.navigator.fetch_col_idx(sheet_id, col_id)
    }

    fn fetch_range(
        &self,
        sheet_id: &SheetId,
        range_id: &logisheets_base::RangeId,
    ) -> Result<logisheets_base::Range> {
        self.range_manager
            .get_range(sheet_id, range_id)
            .ok_or(BasicError::RangeIdNotFound(*range_id))
    }

    fn fetch_cube(&self, cube_id: &logisheets_base::CubeId) -> Result<Cube> {
        self.cube_manager
            .get_cube(cube_id)
            .ok_or(BasicError::CubeIdNotFound(*cube_id))
    }

    fn fetch_ext_ref(
        &mut self,
        ext_ref_id: &logisheets_base::ExtRefId,
    ) -> Result<logisheets_base::ExtRef> {
        self.ext_ref_manager
            .get_ext_ref(ext_ref_id)
            .ok_or(BasicError::ExtRefIdNotFound(*ext_ref_id))
    }
}

impl<'a> SaverTrait for Saver<'a> {
    fn fetch_part_id(&mut self) -> String {
        self.part_count += 1;
        format!("rId{}", self.part_count)
    }

    fn fetch_row_id(&mut self, sheet_id: SheetId, idx: usize) -> RowId {
        self.navigator.fetch_row_id(&sheet_id, idx).unwrap()
    }
}