//! Various bundlers for use with [Distribution::bundle](super::Distribution::bundle).

pub mod dir;

#[cfg(feature = "tar_gz")]
pub mod tar;

#[cfg(feature = "zip")]
pub mod zip;


use std::{any::Any, path::Path};


/// Trait which can be implemented to provide additional
/// bundling variants for use in [Distribution::bundle](super::Distribution::bundle).
///
/// Your implementation is provided with a directory of
/// distribution files and your job is to process them,
/// so that they can be shipped to users.
/// Typically, this involves compressing the directory.
///
/// See [dir::DirBundler] for an example implementation.
pub trait Bundler: Any {
    /// The file extension to use on the resulting distribution file.
    ///
    /// The provided string is appended as-is to the distribution name.
    /// As such, you should specify the extension in full
    /// (typically with a leading dot), for example: .tar.gz
    ///
    /// If you don't want a file extension, or your bundler creates
    /// a directory, you should specify an empty string.
    fn file_extension(&self) -> &str;

    /// To be implemented by each bundler, so that it takes
    /// a directory with distribution files as `in_dir` and
    /// places the bundled distribution in `out_path`.
    ///
    /// The `out_path` parameter is provided as absolute path with
    /// the distribution name and `file_extension()` appended.
    ///
    /// The `metadata` parameter provides additional information
    /// you can use during bundling.
    /// For example, you typically want to place a top-level folder
    /// into archives with the name of the distribution, so that
    /// unpacking does not scatter files into the containing directory.
    fn bundle(&self, in_dir: &Path, out_path: &Path, metadata: &BundleMetadata) -> cicero_core::Result<()>;
}


/// Additional information provided for use during bundling.
#[non_exhaustive]
pub struct BundleMetadata {
    /// The name of the distribution, as provided
    /// when creating a new [super::Distribution].
    pub distribution_name: String,
}
