rquickjs_core/loader/
bundle.rs1use super::{util::resolve_simple, ImportAttributes, Loader, Resolver};
4use crate::{Ctx, Error, Module, Result};
5use alloc::string::String;
6use core::ops::Deref;
7
8pub trait HasByteCode<'bc> {
12 fn get_bytecode(&self) -> &'bc [u8];
13}
14
15impl<'bc> HasByteCode<'bc> for &'bc [u8] {
16 fn get_bytecode(&self) -> &'bc [u8] {
17 self
18 }
19}
20
21pub type ScaBundleData<D> = &'static [(&'static str, D)];
25
26#[cfg(feature = "phf")]
27pub type PhfBundleData<D> = &'static phf::Map<&'static str, D>;
31
32#[derive(Debug, Clone, Copy)]
34pub struct Bundle<T>(pub T);
35
36impl<T> Deref for Bundle<T> {
37 type Target = T;
38
39 fn deref(&self) -> &Self::Target {
40 &self.0
41 }
42}
43
44impl<D> Resolver for Bundle<ScaBundleData<D>> {
45 fn resolve<'js>(
46 &mut self,
47 _ctx: &Ctx<'js>,
48 base: &str,
49 name: &str,
50 _attributes: Option<ImportAttributes<'js>>,
51 ) -> Result<String> {
52 let path = resolve_simple(base, name);
53 if self.iter().any(|(name, _)| *name == path) {
54 Ok(path)
55 } else {
56 Err(Error::new_resolving(base, name))
57 }
58 }
59}
60
61#[cfg(feature = "phf")]
62impl<D> Resolver for Bundle<PhfBundleData<D>> {
63 fn resolve<'js>(
64 &mut self,
65 _ctx: &Ctx<'js>,
66 base: &str,
67 name: &str,
68 _attributes: Option<ImportAttributes<'js>>,
69 ) -> Result<String> {
70 let path = resolve_simple(base, name);
71 if self.contains_key(path.as_str()) {
72 Ok(path)
73 } else {
74 Err(Error::new_resolving(base, name))
75 }
76 }
77}
78
79impl<D> Loader for Bundle<ScaBundleData<D>>
80where
81 D: HasByteCode<'static>,
82{
83 fn load<'js>(
84 &mut self,
85 ctx: &Ctx<'js>,
86 name: &str,
87 _attributes: Option<crate::loader::ImportAttributes<'js>>,
88 ) -> Result<Module<'js>> {
89 if let Some((_, x)) = self.iter().find(|(module_name, _)| *module_name == name) {
90 let module = unsafe { Module::load(ctx.clone(), x.get_bytecode())? };
91 return Ok(module);
92 }
93 Err(Error::new_loading(name))
94 }
95}
96
97#[cfg(feature = "phf")]
98impl<D> Loader for Bundle<PhfBundleData<D>>
99where
100 D: HasByteCode<'static>,
101{
102 fn load<'js>(
103 &mut self,
104 ctx: &Ctx<'js>,
105 name: &str,
106 _attributes: Option<crate::loader::ImportAttributes<'js>>,
107 ) -> Result<Module<'js>> {
108 if let Some(x) = self.get(name) {
109 let module = unsafe { Module::load(ctx.clone(), x.get_bytecode())? };
110 return Ok(module);
111 }
112 Err(Error::new_loading(name))
113 }
114}