numcodecs_wasm_guest/
lib.rs1#[doc(hidden)]
23pub use numcodecs;
24
25#[cfg(doc)]
26use numcodecs::StaticCodec;
27
28#[cfg(target_arch = "wasm32")]
29use ::{
30 numcodecs::{Codec, StaticCodec},
31 schemars::schema_for,
32 serde::Deserialize,
33};
34
35#[cfg(target_arch = "wasm32")]
36mod convert;
37
38#[cfg(all(feature = "registry", target_arch = "wasm32"))]
39mod external;
40
41#[cfg(target_arch = "wasm32")]
42use crate::convert::{
43 from_wit_any_array, into_wit_any_array, into_wit_error, zeros_from_wit_any_array_prototype,
44};
45
46#[doc(hidden)]
47#[expect(clippy::same_length_and_capacity)]
48pub mod bindings {
49 #[cfg(not(feature = "registry"))]
50 wit_bindgen::generate!({
51 world: "numcodecs:abc/exports@0.1.1",
52 with: {
53 "numcodecs:abc/codec@0.1.1": generate,
54 },
55 pub_export_macro: true,
56 });
57 #[cfg(feature = "registry")]
58 wit_bindgen::generate!({
59 world: "numcodecs:abc/exports@0.1.1",
60 with: {
61 "numcodecs:abc/codec@0.1.1": generate,
62 "numcodecs:abc/types@0.1.1": crate::bindings::exports::numcodecs::abc::codec,
64 },
65 pub_export_macro: true,
66 features: ["registry"],
67 });
68}
69
70#[cfg(target_arch = "wasm32")]
71mod wit {
72 pub mod codec {
73 pub use crate::bindings::exports::numcodecs::abc::codec::{Codec, Guest, GuestCodec};
74 }
75
76 #[cfg(feature = "registry")]
77 pub mod registry {
78 pub use crate::bindings::numcodecs::abc::registry::{
79 ExternalCodec, ExternalCodecType, get_external_codec,
80 };
81 }
82
83 pub mod types {
84 pub use crate::bindings::exports::numcodecs::abc::codec::{
86 AnyArray, AnyArrayData, AnyArrayDtype, AnyArrayPrototype, Error, Json, JsonSchema,
87 Usize,
88 };
89 }
90}
91
92#[macro_export]
93macro_rules! export_codec {
113 ($codec:ty) => {
114 #[cfg(target_arch = "wasm32")]
115 const _: () = {
116 type Codec = $codec;
117
118 $crate::bindings::export!(
119 Codec with_types_in $crate::bindings
120 );
121 };
122
123 const _: () = {
124 const fn can_only_export_static_codec<T: $crate::numcodecs::StaticCodec>() {}
125
126 can_only_export_static_codec::<$codec>()
127 };
128 };
129}
130
131#[cfg(target_arch = "wasm32")]
132#[doc(hidden)]
133impl<T: StaticCodec> wit::codec::Guest for T {
134 type Codec = Self;
135
136 fn codec_id() -> String {
137 String::from(<Self as StaticCodec>::CODEC_ID)
138 }
139
140 fn codec_config_schema() -> wit::types::JsonSchema {
141 schema_for!(<Self as StaticCodec>::Config<'static>)
142 .as_value()
143 .to_string()
144 }
145}
146
147#[cfg(target_arch = "wasm32")]
148impl<T: StaticCodec> wit::codec::GuestCodec for T {
149 fn from_config(config: String) -> Result<wit::codec::Codec, wit::types::Error> {
150 let err = match <Self as StaticCodec>::Config::deserialize(
151 &mut serde_json::Deserializer::from_str(&config),
152 ) {
153 Ok(config) => {
154 return Ok(wit::codec::Codec::new(<Self as StaticCodec>::from_config(
155 config,
156 )));
157 }
158 Err(err) => err,
159 };
160
161 let err = format_serde_error::SerdeError::new(config, err);
162 Err(into_wit_error(err))
163 }
164
165 fn encode(
166 &self,
167 data: wit::types::AnyArray,
168 ) -> Result<wit::types::AnyArray, wit::types::Error> {
169 let data = match from_wit_any_array(data) {
170 Ok(data) => data,
171 Err(err) => return Err(into_wit_error(err)),
172 };
173
174 match <Self as Codec>::encode(self, data.into_cow()) {
175 Ok(encoded) => match into_wit_any_array(encoded) {
176 Ok(encoded) => Ok(encoded),
177 Err(err) => Err(into_wit_error(err)),
178 },
179 Err(err) => Err(into_wit_error(err)),
180 }
181 }
182
183 fn decode(
184 &self,
185 encoded: wit::types::AnyArray,
186 ) -> Result<wit::types::AnyArray, wit::types::Error> {
187 let encoded = match from_wit_any_array(encoded) {
188 Ok(encoded) => encoded,
189 Err(err) => return Err(into_wit_error(err)),
190 };
191
192 match <Self as Codec>::decode(self, encoded.into_cow()) {
193 Ok(decoded) => match into_wit_any_array(decoded) {
194 Ok(decoded) => Ok(decoded),
195 Err(err) => Err(into_wit_error(err)),
196 },
197 Err(err) => Err(into_wit_error(err)),
198 }
199 }
200
201 fn decode_into(
202 &self,
203 encoded: wit::types::AnyArray,
204 decoded: wit::types::AnyArrayPrototype,
205 ) -> Result<wit::types::AnyArray, wit::types::Error> {
206 let encoded = match from_wit_any_array(encoded) {
207 Ok(encoded) => encoded,
208 Err(err) => return Err(into_wit_error(err)),
209 };
210
211 let mut decoded = zeros_from_wit_any_array_prototype(decoded);
212
213 match <Self as Codec>::decode_into(self, encoded.view(), decoded.view_mut()) {
214 Ok(()) => match into_wit_any_array(decoded) {
215 Ok(decoded) => Ok(decoded),
216 Err(err) => Err(into_wit_error(err)),
217 },
218 Err(err) => Err(into_wit_error(err)),
219 }
220 }
221
222 fn get_config(&self) -> Result<wit::types::Json, wit::types::Error> {
223 match serde_json::to_string(&<Self as StaticCodec>::get_config(self)) {
224 Ok(config) => Ok(config),
225 Err(err) => Err(into_wit_error(err)),
226 }
227 }
228}