1use anyhow::{anyhow, Result};
2use std::{borrow::Cow, fs, path::Path, str};
3
4use super::bytecode;
5
6#[derive(Default, PartialEq, Copy, Clone)]
9#[allow(dead_code)] pub(crate) enum PluginKind {
11 #[default]
12 User,
13 Default,
14 V2,
15}
16
17impl PluginKind {
18 pub(crate) fn import_namespace(self, plugin: &Plugin) -> Result<String> {
20 match self {
21 PluginKind::V2 => Ok("javy_quickjs_provider_v2".to_string()),
22 PluginKind::User | PluginKind::Default => {
23 let module = walrus::Module::from_buffer(plugin.as_bytes())?;
25 let import_namespace: std::borrow::Cow<'_, [u8]> = module
26 .customs
27 .iter()
28 .find_map(|(_, section)| {
29 if section.name() == "import_namespace" {
30 Some(section)
31 } else {
32 None
33 }
34 })
35 .ok_or_else(|| anyhow!("Plugin is missing import_namespace custom section"))?
36 .data(&Default::default()); Ok(str::from_utf8(&import_namespace)?.to_string())
38 }
39 }
40 }
41}
42
43#[derive(Clone, Debug, Default)]
45pub struct Plugin {
46 bytes: Cow<'static, [u8]>,
47}
48
49impl Plugin {
50 pub fn new(bytes: Cow<'static, [u8]>) -> Self {
52 Plugin { bytes }
53 }
54
55 pub fn new_from_path<P: AsRef<Path>>(path: P) -> Result<Self> {
57 let bytes = fs::read(path)?;
58 Ok(Self::new(bytes.into()))
59 }
60
61 pub fn as_bytes(&self) -> &[u8] {
63 &self.bytes
64 }
65
66 pub(crate) fn compile_source(&self, js_source_code: &[u8]) -> Result<Vec<u8>> {
68 bytecode::compile_source(self.as_bytes(), js_source_code)
69 }
70}