1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Vc, trace::TraceRawVcs};
4use turbo_tasks_fs::{File, FileContent};
5use turbopack_core::{
6 asset::{Asset, AssetContent},
7 ident::AssetIdent,
8 source::Source,
9};
10
11#[derive(
12 PartialOrd,
13 Ord,
14 Eq,
15 PartialEq,
16 Hash,
17 Debug,
18 Copy,
19 Clone,
20 Serialize,
21 Deserialize,
22 TaskInput,
23 TraceRawVcs,
24 NonLocalValue,
25)]
26pub enum WebAssemblySourceType {
27 Binary,
29 Text,
31}
32
33#[turbo_tasks::value]
36#[derive(Clone)]
37pub struct WebAssemblySource {
38 source: ResolvedVc<Box<dyn Source>>,
39 source_ty: WebAssemblySourceType,
40}
41
42#[turbo_tasks::value_impl]
43impl WebAssemblySource {
44 #[turbo_tasks::function]
45 pub fn new(source: ResolvedVc<Box<dyn Source>>, source_ty: WebAssemblySourceType) -> Vc<Self> {
46 Self::cell(WebAssemblySource { source, source_ty })
47 }
48}
49
50#[turbo_tasks::value_impl]
51impl Source for WebAssemblySource {
52 #[turbo_tasks::function]
53 fn ident(&self) -> Vc<AssetIdent> {
54 match self.source_ty {
55 WebAssemblySourceType::Binary => self.source.ident(),
56 WebAssemblySourceType::Text => self
57 .source
58 .ident()
59 .with_path(self.source.ident().path().append("_.wasm".into())),
60 }
61 }
62}
63
64#[turbo_tasks::value_impl]
65impl Asset for WebAssemblySource {
66 #[turbo_tasks::function]
67 async fn content(&self) -> Result<Vc<AssetContent>> {
68 let content = match self.source_ty {
69 WebAssemblySourceType::Binary => return Ok(self.source.content()),
70 WebAssemblySourceType::Text => self.source.content(),
71 };
72
73 let content = content.file_content().await?;
74
75 let FileContent::Content(file) = &*content else {
76 return Ok(AssetContent::file(FileContent::NotFound.cell()));
77 };
78
79 let bytes = file.content().to_bytes()?;
80 let parsed = wat::parse_bytes(&bytes)?;
81
82 Ok(AssetContent::file(File::from(&*parsed).into()))
83 }
84}