whisky_csl/utils/
plutus_data.rs

1use cardano_serialization_lib as csl;
2use whisky_common::data::PlutusDataJson;
3use whisky_common::WError;
4
5/// Extension trait that adds CBOR serialization/deserialization capabilities
6/// to any type implementing `PlutusDataJson`.
7///
8/// This trait is implemented automatically for all types that implement `PlutusDataJson`,
9/// allowing direct conversion to/from CBOR hex strings.
10///
11/// # Example
12///
13/// ```rust,ignore
14/// use whisky_csl::PlutusDataCbor;
15/// use whisky::data::PlutusDataJson;
16///
17/// #[derive(Debug, Clone, ConstrEnum)]
18/// pub enum HydraOrderBookIntent {
19///     PlaceOrderIntent(Box<(Order, MValue)>),
20///     ModifyOrderIntent(Box<(Order, MValue)>),
21/// }
22///
23/// // Deserialize from CBOR
24/// let cbor_hex = "d87a9f...";
25/// let intent = HydraOrderBookIntent::from_cbor(cbor_hex)?;
26///
27/// // Serialize back to CBOR
28/// let cbor_out = intent.to_cbor()?;
29/// ```
30pub trait PlutusDataCbor: PlutusDataJson {
31    /// Parse from CBOR hex string.
32    ///
33    /// This method converts the CBOR hex to JSON using CSL's DetailedSchema,
34    /// then parses it using the type's `from_json` implementation.
35    fn from_cbor(cbor_hex: &str) -> Result<Self, WError>;
36
37    /// Serialize to CBOR hex string.
38    ///
39    /// This method converts the type to JSON using `to_json`,
40    /// then serializes it to CBOR hex using CSL's DetailedSchema.
41    fn to_cbor(&self) -> Result<String, WError>;
42}
43
44impl<T: PlutusDataJson> PlutusDataCbor for T {
45    fn from_cbor(cbor_hex: &str) -> Result<Self, WError> {
46        let csl_data = csl::PlutusData::from_hex(cbor_hex)
47            .map_err(WError::from_err("PlutusDataCbor::from_cbor - invalid CBOR hex"))?;
48
49        let json_str = csl_data
50            .to_json(csl::PlutusDatumSchema::DetailedSchema)
51            .map_err(WError::from_err(
52                "PlutusDataCbor::from_cbor - failed to convert to JSON",
53            ))?;
54
55        let json_value: serde_json::Value = serde_json::from_str(&json_str)
56            .map_err(WError::from_err("PlutusDataCbor::from_cbor - invalid JSON"))?;
57
58        Self::from_json(&json_value)
59    }
60
61    fn to_cbor(&self) -> Result<String, WError> {
62        let json_str = self.to_json_string();
63
64        let csl_data = csl::PlutusData::from_json(&json_str, csl::PlutusDatumSchema::DetailedSchema)
65            .map_err(WError::from_err("PlutusDataCbor::to_cbor - failed to parse JSON"))?;
66
67        Ok(csl_data.to_hex())
68    }
69}