1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
use crate::{
core::writers::{csv_writer, json_writer, sqlite_writer},
helpers::file_system_helpers::{ensure_folder_exists, WORKSPACE_PATHS},
models::Machine,
progress::ProgressCallback,
};
use std::{
collections::HashMap,
error::Error,
fmt,
path::{Path, PathBuf},
};
/// Writes machine data to the specified export file type.
///
/// This function handles the export of machine data to the chosen format (`SQLite`, `JSON`, or `CSV`)
/// by creating the necessary export folder in the workspace path and invoking the appropriate writer function.
/// It ensures that the target directory exists, then delegates the writing task to the relevant module
/// based on the selected `ExportFileType`. Progress updates and messages are provided via a callback function.
///
/// # Parameters
/// - `export_file_type`: An `ExportFileType` enum specifying the format for data export. Supported types are:
/// - `ExportFileType::Sqlite`: Exports data to a SQLite database file.
/// - `ExportFileType::Json`: Exports data to a JSON file.
/// - `ExportFileType::Csv`: Exports data to a CSV file.
/// - `workspace_path`: A reference to a `Path` representing the base directory where the exported files will be stored.
/// - `machines`: A reference to a `HashMap` where keys are machine names and values are `Machine` structs containing
/// detailed information about each MAME machine.
/// - `progress_callback`: A callback function of type `ProgressCallback` that provides status updates and progress
/// information during the export process. The callback receives a `ProgressInfo` struct containing `progress`, `total`,
/// `message`, and `callback_type`.
///
/// # Returns
/// Returns a `Result<PathBuf, Box<dyn Error + Send + Sync>>`:
/// - On success: Contains a `PathBuf` representing the path to the folder where the export files are stored.
/// - On failure: Contains an error if the export folder cannot be created or if there is an issue during the writing process.
///
/// # Errors
/// This function will return an error if:
/// - The export folder cannot be created due to permission issues or file system errors.
/// - The writing process fails for the selected export file type due to data formatting issues or I/O errors.
///
/// # Callback
/// The progress callback function provides real-time updates on the export process. It receives:
/// - `progress`: The current progress of the export operation (e.g., number of records processed).
/// - `total`: The total number of items to be exported.
/// - `message`: A status message indicating the current operation (e.g., "Creating export folder", "Writing to file").
/// - `callback_type`: The type of callback, such as `CallbackType::Info`, `CallbackType::Error`, `CallbackType::Progress`, or `CallbackType::Finish`.
///
/// # Example Sqlite
#[doc = docify::embed!("examples/write_sqlite.rs", main)]
///
/// # Example Csv
#[doc = docify::embed!("examples/write_csv.rs", main)]
///
/// # Example Json
#[doc = docify::embed!("examples/write_json.rs", main)]
///
pub fn write_files(
export_file_type: ExportFileType,
workspace_path: &Path,
machines: &HashMap<String, Machine>,
progress_callback: ProgressCallback,
) -> Result<PathBuf, Box<dyn Error + Send + Sync>> {
let export_folder = workspace_path
.join(WORKSPACE_PATHS.export_path)
.join(export_file_type.to_string().to_lowercase());
let folder_created = ensure_folder_exists(&export_folder);
if let Err(err) = folder_created {
return Err(Box::new(err));
}
match export_file_type {
ExportFileType::Sqlite => {
let data_base_path = export_folder.join("machines.db");
sqlite_writer::write_sqlite(
&data_base_path.to_string_lossy(),
&machines,
progress_callback,
)?;
}
ExportFileType::Json => {
json_writer::write_json(
&export_folder.to_string_lossy(),
&machines,
progress_callback,
)?;
}
ExportFileType::Csv => {
csv_writer::write_csv(
&export_folder.to_string_lossy(),
&machines,
progress_callback,
)?;
}
}
Ok(export_folder)
}
/// Represents the file type to be used for data export.
///
/// The `ExportFileType` enum defines the different formats supported for exporting data,
/// allowing the caller to choose between database, structured data, and tabular formats.
/// This is particularly useful in scenarios where data needs to be shared, stored, or analyzed
/// in various ways.
///
/// # Variants
/// - `Sqlite`: Exports the data to a SQLite database file, suitable for structured storage and complex queries.
/// - `Json`: Exports the data to a JSON (JavaScript Object Notation) file, ideal for web applications and data interchange.
/// - `Csv`: Exports the data to a CSV (Comma-Separated Values) file, useful for spreadsheet applications and basic data analysis.
///
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExportFileType {
/// Exports data to a SQLite database file.
Sqlite,
/// Exports data to a JSON file.
Json,
/// Exports data to a CSV file.
Csv,
}
/// Implements the `fmt::Display` trait for `ExportFileType`.
///
/// This allows instances of `ExportFileType` to be formatted as strings,
/// making it easy to display or print the enum values in a user-friendly way.
impl fmt::Display for ExportFileType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Match each variant to its corresponding string representation
let as_str = match self {
ExportFileType::Sqlite => "sqlite",
ExportFileType::Json => "json",
ExportFileType::Csv => "csv",
};
// Write the string representation to the formatter
write!(f, "{}", as_str)
}
}