use crate::{pcd::Member, process::Process}; use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use sp_client::bitcoin::hex::{DisplayHex, FromHex}; use sp_client::bitcoin::OutPoint; use std::collections::{BTreeMap, HashMap}; use tsify::Tsify; #[derive(Debug, Serialize, Deserialize, Tsify)] #[tsify(from_wasm_abi)] pub struct OutPointMemberMap(#[serde(with = "members_map")] pub HashMap); #[derive(Debug, Serialize, Deserialize, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct OutPointProcessMap(#[serde(with = "outpoint_map")] pub HashMap); // These helper functions convert a [u8; 32] to/from a hex string. pub(crate) fn serialize_hex(bytes: &[u8; 32], serializer: S) -> Result where S: Serializer, { let hex_str = bytes.to_lower_hex_string(); serializer.serialize_str(&hex_str) } pub(crate) fn deserialize_hex<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error> where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; let bytes = Vec::from_hex(&s).map_err(D::Error::custom)?; if bytes.len() != 32 { return Err(D::Error::custom("Invalid length for [u8;32]")); } let mut arr = [0u8; 32]; arr.copy_from_slice(&bytes); Ok(arr) } pub mod members_map { use super::*; use crate::pcd::Member; pub fn serialize(map: &HashMap, serializer: S) -> Result where S: Serializer, { let map: HashMap = map.iter().map(|(k, v)| (*k, v.to_owned())).collect(); map.serialize(serializer) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let map: HashMap = HashMap::deserialize(deserializer)?; Ok(map) } } pub mod outpoint_map { use super::*; use crate::process::Process; pub fn serialize(map: &HashMap, serializer: S) -> Result where S: Serializer, { // Convert OutPoint keys to Strings let map: HashMap = map .into_iter() .map(|(k, v)| (k.to_string(), v.clone())) .collect(); // Serialize as HashMap map.serialize(serializer) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { // Deserialize as HashMap let map: HashMap = HashMap::deserialize(deserializer)?; // Convert String keys back to OutPoint let result: Result, D::Error> = map .into_iter() .map(|(k, v)| { let outpoint = k.parse().map_err(serde::de::Error::custom)?; Ok((outpoint, v)) }) .collect(); result } } // Custom module for converting a BTreeMap using hex conversion. pub mod hex_array_btree { use super::*; // Serializes a BTreeMap as a BTreeMap // where the value is a hex-encoded string. pub fn serialize(map: &BTreeMap, serializer: S) -> Result where S: Serializer, { // Convert each [u8; 32] to a hex string. let hex_map: BTreeMap = map .iter() .map(|(k, v)| (k.clone(), v.to_lower_hex_string())) .collect(); hex_map.serialize(serializer) } // Deserializes a BTreeMap from a BTreeMap // where the value is expected to be a hex-encoded string. pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { // Deserialize into a temporary map with hex string values. let hex_map: BTreeMap = BTreeMap::deserialize(deserializer)?; let mut map = BTreeMap::new(); // Convert each hex string back into a [u8; 32]. for (key, hex_str) in hex_map { let bytes = Vec::from_hex(&hex_str).map_err(D::Error::custom)?; if bytes.len() != 32 { return Err(D::Error::custom("Invalid length for [u8;32]")); } let mut array = [0u8; 32]; array.copy_from_slice(&bytes); map.insert(key, array); } Ok(map) } }