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