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}