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(target_arch = "wasm32")]
39use crate::{
40 bindings::exports::numcodecs::abc::codec as wit,
41 convert::{
42 from_wit_any_array, into_wit_any_array, into_wit_error, zeros_from_wit_any_array_prototype,
43 },
44};
45
46#[doc(hidden)]
47#[expect(clippy::same_length_and_capacity)]
48pub mod bindings {
49 wit_bindgen::generate!({
50 world: "numcodecs:abc/exports@0.1.1",
51 with: {
52 "numcodecs:abc/codec@0.1.1": generate,
53 },
54 pub_export_macro: true,
55 });
56}
57
58#[macro_export]
59macro_rules! export_codec {
79 ($codec:ty) => {
80 #[cfg(target_arch = "wasm32")]
81 const _: () = {
82 type Codec = $codec;
83
84 $crate::bindings::export!(
85 Codec with_types_in $crate::bindings
86 );
87 };
88
89 const _: () = {
90 const fn can_only_export_static_codec<T: $crate::numcodecs::StaticCodec>() {}
91
92 can_only_export_static_codec::<$codec>()
93 };
94 };
95}
96
97#[cfg(target_arch = "wasm32")]
98#[doc(hidden)]
99impl<T: StaticCodec> wit::Guest for T {
100 type Codec = Self;
101
102 fn codec_id() -> String {
103 String::from(<Self as StaticCodec>::CODEC_ID)
104 }
105
106 fn codec_config_schema() -> wit::JsonSchema {
107 schema_for!(<Self as StaticCodec>::Config<'static>)
108 .as_value()
109 .to_string()
110 }
111}
112
113#[cfg(target_arch = "wasm32")]
114impl<T: StaticCodec> wit::GuestCodec for T {
115 fn from_config(config: String) -> Result<wit::Codec, wit::Error> {
116 let err = match <Self as StaticCodec>::Config::deserialize(
117 &mut serde_json::Deserializer::from_str(&config),
118 ) {
119 Ok(config) => return Ok(wit::Codec::new(<Self as StaticCodec>::from_config(config))),
120 Err(err) => err,
121 };
122
123 let err = format_serde_error::SerdeError::new(config, err);
124 Err(into_wit_error(err))
125 }
126
127 fn encode(&self, data: wit::AnyArray) -> Result<wit::AnyArray, wit::Error> {
128 let data = match from_wit_any_array(data) {
129 Ok(data) => data,
130 Err(err) => return Err(into_wit_error(err)),
131 };
132
133 match <Self as Codec>::encode(self, data.into_cow()) {
134 Ok(encoded) => match into_wit_any_array(encoded) {
135 Ok(encoded) => Ok(encoded),
136 Err(err) => Err(into_wit_error(err)),
137 },
138 Err(err) => Err(into_wit_error(err)),
139 }
140 }
141
142 fn decode(&self, encoded: wit::AnyArray) -> Result<wit::AnyArray, wit::Error> {
143 let encoded = match from_wit_any_array(encoded) {
144 Ok(encoded) => encoded,
145 Err(err) => return Err(into_wit_error(err)),
146 };
147
148 match <Self as Codec>::decode(self, encoded.into_cow()) {
149 Ok(decoded) => match into_wit_any_array(decoded) {
150 Ok(decoded) => Ok(decoded),
151 Err(err) => Err(into_wit_error(err)),
152 },
153 Err(err) => Err(into_wit_error(err)),
154 }
155 }
156
157 fn decode_into(
158 &self,
159 encoded: wit::AnyArray,
160 decoded: wit::AnyArrayPrototype,
161 ) -> Result<wit::AnyArray, wit::Error> {
162 let encoded = match from_wit_any_array(encoded) {
163 Ok(encoded) => encoded,
164 Err(err) => return Err(into_wit_error(err)),
165 };
166
167 let mut decoded = zeros_from_wit_any_array_prototype(decoded);
168
169 match <Self as Codec>::decode_into(self, encoded.view(), decoded.view_mut()) {
170 Ok(()) => match into_wit_any_array(decoded) {
171 Ok(decoded) => Ok(decoded),
172 Err(err) => Err(into_wit_error(err)),
173 },
174 Err(err) => Err(into_wit_error(err)),
175 }
176 }
177
178 fn get_config(&self) -> Result<wit::Json, wit::Error> {
179 match serde_json::to_string(&<Self as StaticCodec>::get_config(self)) {
180 Ok(config) => Ok(config),
181 Err(err) => Err(into_wit_error(err)),
182 }
183 }
184}