use std::{ collections::HashMap, sync::{LazyLock, Mutex}, }; use crate::middleware::{DynError, Error, Hash, Params, Pod, PodId, PodType, RecursivePod, Result}; type DeserializeFn = fn( params: Params, data: serde_json::Value, vds_root: Hash, id: PodId, ) -> Result, Box>; static DESERIALIZERS: LazyLock>> = LazyLock::new(backend::deserializers_default); pub fn register_pod_deserializer(pod_type: usize, deserialize_fn: DeserializeFn) { DESERIALIZERS .lock() .unwrap() .insert(pod_type, deserialize_fn); } pub fn deserialize_pod( pod_type: usize, params: Params, id: PodId, vds_root: Hash, data: serde_json::Value, ) -> Result> { let deserialize_fn: DeserializeFn = *DESERIALIZERS .lock() .unwrap() .get(&pod_type) .ok_or(Error::custom(format!( "pod deserializer for pod_type={} not registered. See https://github.com/0xPARC/pod2/wiki/PodType for pod type assignments.", pod_type )))?; deserialize_fn(params, data, vds_root, id) .map_err(|e| Error::custom(format!("deserialize error: {:?}", e))) } pub fn deserialize_signed_pod( pod_type: usize, id: PodId, data: serde_json::Value, ) -> Result> { backend::deserialize_signed_pod(pod_type, id, data) } #[cfg(feature = "backend_plonky2")] mod backend { use super::*; use crate::backends::plonky2::{ emptypod::EmptyPod, mainpod::MainPod, mock::{emptypod::MockEmptyPod, mainpod::MockMainPod, signedpod::MockSignedPod}, signedpod::SignedPod, }; pub(super) fn deserializers_default() -> Mutex> { let mut map: HashMap = HashMap::new(); map.insert(PodType::Empty as usize, EmptyPod::deserialize_data); map.insert(PodType::Main as usize, MainPod::deserialize_data); map.insert(PodType::MockEmpty as usize, MockEmptyPod::deserialize_data); map.insert(PodType::MockMain as usize, MockMainPod::deserialize_data); Mutex::new(map) } pub(super) fn deserialize_signed_pod( pod_type: usize, id: PodId, data: serde_json::Value, ) -> Result> { if pod_type == PodType::MockSigned as usize { MockSignedPod::deserialize(id, data) .map_err(|e| Error::custom(format!("deserialize error: {:?}", e))) } else if pod_type == PodType::Signed as usize { SignedPod::deserialize(id, data) .map_err(|e| Error::custom(format!("deserialize error: {:?}", e))) } else { Err(Error::custom(format!( "unexpected pod_type={} for deserialize_signed_pod", pod_type ))) } } }