logisheets_controller 0.7.0

the core of LogiSheets
Documentation
use itertools::Itertools;
use logisheets_workbook::{
    prelude::{CtExternalReference, CtExternalReferences, CtSheet, CtSheets, WorkbookPart},
    workbook::{DocProps, Wb, Worksheet, Xl},
};
use std::collections::HashMap;

use crate::{
    cell_attachments::CellAttachmentsManager,
    container::DataContainer,
    ext_book_manager::ExtBooksManager,
    file_saver::{
        external_links::save_external_link, styles::save_sheet_style, worksheet::save_sheets,
    },
    formula_manager::FormulaManager,
    id_manager::{SheetIdManager, TextIdManager},
    settings::Settings,
    style_manager::StyleManager,
    theme_manager::ThemeManager,
    workbook::sheet_pos_manager::SheetPosManager,
};

use super::{error::SaveError, sst::save_sst, SaverTrait};

pub fn save_workbook<S: SaverTrait>(
    data_container: &DataContainer,
    formula_manager: &FormulaManager,
    attachment_manager: &CellAttachmentsManager,
    sheet_pos_manager: &SheetPosManager,
    sheet_id_manager: &SheetIdManager,
    style_manager: &StyleManager,
    ext_book_manager: &ExtBooksManager,
    theme_manager: &ThemeManager,
    text_id_manager: &TextIdManager,
    settings: &Settings,
    saver: &mut S,
) -> Result<Wb, SaveError> {
    let mut worksheets: HashMap<String, Worksheet> = HashMap::new();
    let mut ct_sheets: Vec<CtSheet> = vec![];

    sheet_id_manager
        .get_all_ids()
        .into_iter()
        .flat_map(|id| {
            let sheet_data_container = data_container
                .get_sheet_container(id)
                .ok_or(SaveError::SheetIdPosError(id))?;
            save_sheets(
                id,
                sheet_data_container,
                formula_manager,
                attachment_manager,
                sheet_pos_manager,
                sheet_id_manager,
                settings,
                saver,
            )
        })
        .sorted_by_key(|a| a.0)
        .for_each(|(_, ct_sheet, worksheet)| {
            worksheets.insert(ct_sheet.id.clone(), worksheet);
            ct_sheets.push(ct_sheet);
        });
    let ct_sheets = CtSheets { sheets: ct_sheets };
    let styles = save_sheet_style(style_manager, saver);
    let style_id = saver.fetch_part_id();
    let (external_links, ct_references) = {
        let mut result = HashMap::new();
        let links = save_external_link(ext_book_manager, saver);
        let mut ct_references = Vec::with_capacity(links.len());
        links.into_iter().for_each(|link| {
            let id = saver.fetch_part_id();
            ct_references.push(CtExternalReference { id: id.clone() });
            result.insert(id, link);
        });
        (result, ct_references)
    };
    let theme = {
        if theme_manager.theme.is_none() {
            None
        } else {
            let t = theme_manager.clone().theme.unwrap();
            Some((saver.fetch_part_id(), t))
        }
    };
    let sst_part = save_sst(text_id_manager);
    let sst = if let Some(part) = sst_part {
        let id = saver.fetch_part_id();
        Some((id, part))
    } else {
        None
    };
    let workbook = Wb {
        xl: Xl {
            workbook_part: get_workbook(ct_sheets, ct_references),
            styles: (style_id, styles),
            sst,
            worksheets,
            external_links,
            theme,
        },
        doc_props: DocProps::default(),
    };
    Ok(workbook)
}

fn get_workbook(ct_sheets: CtSheets, ext_references: Vec<CtExternalReference>) -> WorkbookPart {
    let external_references = if ext_references.is_empty() {
        None
    } else {
        Some(CtExternalReferences {
            external_references: ext_references,
        })
    };
    WorkbookPart {
        file_version: None,
        file_sharing: None,
        workbook_pr: None,
        workbook_protection: None,
        book_views: None,
        sheets: ct_sheets,
        function_groups: None,
        external_references,
        defined_names: None,
        calc_pr: None,
        ole_size: None,
        custom_workbook_views: None,
        pivot_caches: None,
        smart_tag_pr: None,
        smart_tag_types: None,
        web_publishing: None,
        file_recovery_pr: None,
        web_publish_objects: None,
        conformance: None,
    }
}