#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use use_js_module::JsModuleSpecifier;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum JsImportKind {
Default,
Named,
Namespace,
SideEffect,
TypeOnly,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct JsImportSpecifier {
imported: Option<String>,
local: Option<String>,
}
impl JsImportSpecifier {
#[must_use]
pub fn new(imported: Option<&str>, local: Option<&str>) -> Self {
Self {
imported: clean_optional(imported),
local: clean_optional(local),
}
}
#[must_use]
pub fn named(imported: &str, local: Option<&str>) -> Self {
Self::new(Some(imported), local)
}
#[must_use]
pub fn default(local: &str) -> Self {
Self::new(None, Some(local))
}
#[must_use]
pub fn namespace(local: &str) -> Self {
Self::new(Some("*"), Some(local))
}
#[must_use]
pub fn imported(&self) -> Option<&str> {
self.imported.as_deref()
}
#[must_use]
pub fn local(&self) -> Option<&str> {
self.local.as_deref()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct JsImportStatementParts {
kind: JsImportKind,
source: JsModuleSpecifier,
specifiers: Vec<JsImportSpecifier>,
}
impl JsImportStatementParts {
#[must_use]
pub const fn new(kind: JsImportKind, source: JsModuleSpecifier) -> Self {
Self {
kind,
source,
specifiers: Vec::new(),
}
}
#[must_use]
pub fn with_specifier(mut self, specifier: JsImportSpecifier) -> Self {
self.specifiers.push(specifier);
self
}
#[must_use]
pub const fn kind(&self) -> JsImportKind {
self.kind
}
#[must_use]
pub const fn source(&self) -> &JsModuleSpecifier {
&self.source
}
#[must_use]
pub fn specifiers(&self) -> &[JsImportSpecifier] {
&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::{JsImportKind, JsImportSpecifier, JsImportStatementParts};
use use_js_module::{JsModuleSpecifier, JsModuleSpecifierError};
#[test]
fn models_named_import_metadata() -> Result<(), JsModuleSpecifierError> {
let source = JsModuleSpecifier::new("react")?;
let parts = JsImportStatementParts::new(JsImportKind::Named, source)
.with_specifier(JsImportSpecifier::named("useState", Some("state")));
assert_eq!(parts.kind(), JsImportKind::Named);
assert_eq!(parts.source().as_str(), "react");
assert_eq!(parts.specifiers()[0].imported(), Some("useState"));
assert_eq!(parts.specifiers()[0].local(), Some("state"));
Ok(())
}
}