use std::sync::Arc;
use derive_more::Debug;
use napi::{Either, bindgen_prelude::FnArgs};
use napi_derive::napi;
use rspack_napi::threadsafe_function::ThreadsafeFunction;
use rspack_plugin_progress::{ProgressPluginDisplayOptions, ProgressPluginOptions};
type HandlerFn = ThreadsafeFunction<FnArgs<(f64, String, Vec<String>)>, ()>;
#[derive(Debug)]
#[napi(object, object_to_js = false)]
pub struct RawProgressPluginOptions {
pub prefix: Option<String>,
pub profile: Option<bool>,
pub template: Option<String>,
pub tick: Option<Either<String, Vec<String>>>,
pub progress_chars: Option<String>,
#[debug(skip)]
#[napi(ts_type = "(percent: number, msg: string, items: string[]) => void")]
pub handler: Option<HandlerFn>,
}
impl From<RawProgressPluginOptions> for ProgressPluginOptions {
fn from(value: RawProgressPluginOptions) -> Self {
if let Some(f) = value.handler {
Self::Handler(Arc::new(move |percent, msg, items| {
let f = f.clone();
Box::pin(async move { f.call_with_sync((percent, msg, items).into()).await })
}))
} else {
Self::Default(ProgressPluginDisplayOptions {
prefix: value.prefix.unwrap_or_default(),
profile: value.profile.unwrap_or_default(),
template: value.template.unwrap_or(
"● {prefix:.bold} {bar:25.green/white.dim} ({percent}%) {wide_msg:.dim}".to_string(),
),
progress_chars: value.progress_chars.unwrap_or("━━".to_string()),
tick_strings: value.tick.map(|tick| match tick {
Either::A(str) => str.chars().map(|c| c.to_string()).collect(),
Either::B(vec) => vec,
}),
})
}
}
}