1#![deny(warnings)]
2
3use std::any::type_name;
4
5use anyhow::Context;
6use napi::Status;
7use serde::de::DeserializeOwned;
8
9pub trait MapErr<T>: Into<Result<T, anyhow::Error>> {
10 fn convert_err(self) -> napi::Result<T> {
11 self.into()
12 .map_err(|err| napi::Error::new(Status::GenericFailure, format!("{err:?}")))
13 }
14}
15
16impl<T> MapErr<T> for Result<T, anyhow::Error> {}
17
18pub fn get_deserialized<T, B>(buffer: B) -> napi::Result<T>
19where
20 T: DeserializeOwned,
21 B: AsRef<[u8]>,
22{
23 let mut deserializer = serde_json::Deserializer::from_slice(buffer.as_ref());
24 deserializer.disable_recursion_limit();
25
26 let v = T::deserialize(&mut deserializer)
27 .with_context(|| {
28 format!(
29 "Failed to deserialize buffer as {}\nJSON: {}",
30 type_name::<T>(),
31 String::from_utf8_lossy(buffer.as_ref())
32 )
33 })
34 .convert_err()?;
35
36 Ok(v)
37}
38
39pub fn deserialize_json<T>(json: &str) -> Result<T, serde_json::Error>
40where
41 T: DeserializeOwned,
42{
43 let mut deserializer = serde_json::Deserializer::from_str(json);
44 deserializer.disable_recursion_limit();
45
46 T::deserialize(&mut deserializer)
47}