lib.rs
1 use duper::{ 2 DuperIdentifierTryFromError, DuperObjectTryFromError, DuperParser, DuperTemporalTryFromError, 3 DuperValue, PrettyPrinter, Serializer, 4 }; 5 use napi::{Env, bindgen_prelude::Object}; 6 use napi_derive::napi; 7 8 use crate::{ 9 de::DuperMetaDeserializer, 10 ser::{DuperMetaSerializer, SerdeError}, 11 }; 12 13 mod de; 14 mod ser; 15 16 #[derive(Debug, thiserror::Error)] 17 pub enum DuperError { 18 #[error("Parse error: {0}")] 19 Parse(String), 20 #[error("serde_json error: {0}")] 21 SerdeJson(#[from] serde_json::Error), 22 #[error("Serde error: {0}")] 23 Serde(#[from] SerdeError), 24 #[error("Invalid serialization options: {0}")] 25 SerializeOptions(&'static str), 26 #[error("Identifier error: {0}")] 27 InvalidIdentifier(#[from] DuperIdentifierTryFromError<'static>), 28 #[error("Object error: {0}")] 29 InvalidObject(#[from] DuperObjectTryFromError<'static>), 30 #[error("Temporal error: {0}")] 31 InvalidTemporal(#[from] DuperTemporalTryFromError<'static>), 32 } 33 34 #[napi] 35 pub fn parse(env: &Env, input: String, parse_any: bool) -> anyhow::Result<Object<'_>> { 36 let value = match parse_any { 37 true => DuperParser::parse_duper_value(&input), 38 false => DuperParser::parse_duper_trunk(&input), 39 } 40 .map_err(|err| { 41 DuperError::Parse( 42 DuperParser::prettify_error(&input, &err, None).unwrap_or_else(|_| format!("{err:?}")), 43 ) 44 })?; 45 Ok(value.serialize_meta(&DuperMetaSerializer::new(env))?) 46 } 47 48 #[napi(object)] 49 pub struct SerializeOptions { 50 pub indent: Option<String>, 51 pub strip_identifiers: bool, 52 pub minify: bool, 53 } 54 55 #[napi] 56 pub fn serialize( 57 env: &Env, 58 value: Object, 59 options: Option<SerializeOptions>, 60 ) -> anyhow::Result<String> { 61 let SerializeOptions { 62 indent, 63 strip_identifiers, 64 minify, 65 } = options.unwrap_or(SerializeOptions { 66 indent: None, 67 strip_identifiers: false, 68 minify: false, 69 }); 70 if let Some(indent) = indent { 71 if minify { 72 Err(DuperError::SerializeOptions( 73 "Cannot serialize Duper value with both indent and minify options", 74 ) 75 .into()) 76 } else { 77 Ok(PrettyPrinter::new(strip_identifiers, indent.as_ref()) 78 .map_err(DuperError::SerializeOptions)? 79 .pretty_print(&DuperValue::deserialize_meta(DuperMetaDeserializer { 80 env, 81 object: value, 82 })?)) 83 } 84 } else { 85 Ok( 86 Serializer::new(strip_identifiers, minify).serialize(&DuperValue::deserialize_meta( 87 DuperMetaDeserializer { env, object: value }, 88 )?), 89 ) 90 } 91 }