actyx_sdk/event/
opaque.rs1use crate::types::ArcVal;
2use libipld::{
3 cbor::DagCborCodec,
4 codec::{Decode, Encode},
5 raw_value::RawValue,
6};
7use serde::de::Error;
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use std::sync::Arc;
10
11#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd)]
16#[cfg_attr(feature = "dataflow", derive(Abomonation))]
17pub struct Opaque(ArcVal<[u8]>);
18
19impl Opaque {
20 pub fn new(bytes: Arc<[u8]>) -> Self {
21 Opaque(bytes.into())
22 }
23
24 pub fn from_bytes(bytes: &[u8]) -> Self {
25 Opaque(ArcVal::clone_from_unsized(bytes))
26 }
27
28 pub fn is_empty(&self) -> bool {
29 self.0.is_empty()
30 }
31
32 pub fn len(&self) -> usize {
33 self.0.len()
34 }
35
36 pub fn rough_size(&self) -> usize {
38 self.len() + 16
39 }
40}
41
42impl AsRef<[u8]> for Opaque {
43 fn as_ref(&self) -> &[u8] {
44 self.0.as_ref()
45 }
46}
47
48impl Serialize for Opaque {
49 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
50 let mut deserializer = serde_cbor::Deserializer::from_slice(&self.0);
51 serde_transcode::transcode(&mut deserializer, serializer)
52 }
53}
54
55impl<'de> Deserialize<'de> for Opaque {
56 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
57 let res = Vec::new();
58 let mut serializer = serde_cbor::Serializer::new(res);
59 serde_transcode::transcode(deserializer, &mut serializer).map_err(D::Error::custom)?;
60 let res = serializer.into_inner();
61 Ok(Opaque(ArcVal::from_boxed(res.into())))
62 }
63}
64
65impl Encode<DagCborCodec> for Opaque {
66 fn encode<W: std::io::Write>(&self, _c: DagCborCodec, w: &mut W) -> anyhow::Result<()> {
67 Ok(w.write_all(self.as_ref())?)
69 }
70}
71
72impl Decode<DagCborCodec> for Opaque {
73 fn decode<R: std::io::Read + std::io::Seek>(c: DagCborCodec, r: &mut R) -> anyhow::Result<Self> {
74 let tmp = RawValue::<DagCborCodec>::decode(c, r)?;
75 Ok(Self(ArcVal::from_boxed(tmp.into())))
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82 use crate::from_cbor_me;
83 use libipld::codec::Codec;
84 use serde_json::json;
85
86 #[test]
87 fn opaque_dag_cbor_roundtrip() -> anyhow::Result<()> {
88 let text = "";
89 let o1: Opaque = serde_json::from_value(json!([text]))?;
91 let tmp = DagCborCodec.encode(&o1)?;
92 let expected = from_cbor_me(
93 r#"
9481 # array(1)
95 60 # text(0)
96 # ""
97"#,
98 )?;
99 assert_eq!(tmp, expected);
100 let o2: Opaque = DagCborCodec.decode(&tmp)?;
101 assert_eq!(o1, o2);
102 Ok(())
103 }
104
105 #[test]
106 fn u128_is_f64() {
107 let text = format!("{}", u128::max_value());
109 let value: serde_json::Value = serde_json::from_str(&text).unwrap();
110 assert!(value.is_f64());
111 }
112
113 #[test]
114 fn i128_is_f64() {
115 let text = format!("{}", i128::min_value());
117 let value: serde_json::Value = serde_json::from_str(&text).unwrap();
118 assert!(value.is_f64());
119 }
120}