#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use use_js_module::JsModuleSpecifier;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum JsExportKind {
Default,
Named,
Namespace,
TypeOnly,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct JsExportSpecifier {
local: Option<String>,
exported: Option<String>,
}
impl JsExportSpecifier {
#[must_use]
pub fn new(local: Option<&str>, exported: Option<&str>) -> Self {
Self {
local: clean_optional(local),
exported: clean_optional(exported),
}
}
#[must_use]
pub fn named(local: &str, exported: Option<&str>) -> Self {
Self::new(Some(local), exported)
}
#[must_use]
pub fn default(local: &str) -> Self {
Self::new(Some(local), Some("default"))
}
#[must_use]
pub fn local(&self) -> Option<&str> {
self.local.as_deref()
}
#[must_use]
pub fn exported(&self) -> Option<&str> {
self.exported.as_deref()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct JsExportStatementParts {
kind: JsExportKind,
source: Option<JsModuleSpecifier>,
specifiers: Vec<JsExportSpecifier>,
}
impl JsExportStatementParts {
#[must_use]
pub const fn new(kind: JsExportKind) -> Self {
Self {
kind,
source: None,
specifiers: Vec::new(),
}
}
#[must_use]
pub fn with_source(mut self, source: JsModuleSpecifier) -> Self {
self.source = Some(source);
self
}
#[must_use]
pub fn with_specifier(mut self, specifier: JsExportSpecifier) -> Self {
self.specifiers.push(specifier);
self
}
#[must_use]
pub const fn kind(&self) -> JsExportKind {
self.kind
}
#[must_use]
pub const fn source(&self) -> Option<&JsModuleSpecifier> {
self.source.as_ref()
}
#[must_use]
pub fn specifiers(&self) -> &[JsExportSpecifier] {
&self.specifiers
}
}
fn clean_optional(value: Option<&str>) -> Option<String> {
value.and_then(|text| {
let trimmed = text.trim();
(!trimmed.is_empty()).then(|| trimmed.to_string())
})
}
#[cfg(test)]
mod tests {
use super::{JsExportKind, JsExportSpecifier, JsExportStatementParts};
use use_js_module::{JsModuleSpecifier, JsModuleSpecifierError};
#[test]
fn models_re_export_metadata() -> Result<(), JsModuleSpecifierError> {
let source = JsModuleSpecifier::new("./button.js")?;
let parts = JsExportStatementParts::new(JsExportKind::Named)
.with_source(source)
.with_specifier(JsExportSpecifier::named("Button", Some("Button")));
assert_eq!(parts.kind(), JsExportKind::Named);
assert_eq!(
parts.source().map(JsModuleSpecifier::as_str),
Some("./button.js")
);
assert_eq!(parts.specifiers()[0].local(), Some("Button"));
Ok(())
}
}