use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ImportMap {
imports: BTreeMap<String, String>,
}
impl ImportMap {
pub fn new() -> Self {
Self {
imports: BTreeMap::new(),
}
}
pub fn register(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.imports.insert(key.into(), value.into());
self
}
pub fn merge(&mut self, other: ImportMap) {
for (key, value) in other.imports {
self.imports.insert(key, value);
}
}
pub fn to_json(&self) -> serde_json::Result<String> {
serde_json::to_string(self)
}
pub fn to_html(&self) -> serde_json::Result<String> {
self.to_json()
.map(|json| format!(r#"<script type="importmap">{json}</script>"#))
}
}
impl Default for ImportMap {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_importmap() {
let mut map = ImportMap::new();
map.register("svelte", "/_app/svelte.js");
assert_eq!(
map.to_html().unwrap(),
r#"<script type="importmap">{"imports":{"svelte":"/_app/svelte.js"}}</script>"#
);
}
#[test]
fn test_default_importmap() {
let map = ImportMap::default();
assert!(map.imports.is_empty());
}
#[test]
fn test_merge() {
let mut map1 = ImportMap::new();
map1.register("a", "path/a");
map1.register("b", "path/b");
let mut map2 = ImportMap::new();
map2.register("b", "path/b2");
map2.register("c", "path/c");
map1.merge(map2);
let json = map1.to_json().unwrap();
assert!(json.contains(r#""a":"path/a""#));
assert!(json.contains(r#""b":"path/b2""#));
assert!(json.contains(r#""c":"path/c""#));
}
}