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