use serde::de::{self, SeqAccess, Visitor};
use serde::ser::{SerializeSeq, SerializeTuple};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use bb_ir::slot_value::{wire_decoder_registry, SlotValue as IrSlotValue};
use bb_ir::types::{
TYPE_ADDRESS_VEC, TYPE_BYTES, TYPE_COMPOSITE, TYPE_MULTIADDRESS, TYPE_PEER_ID,
TYPE_PEER_ID_VEC, TYPE_TRIGGER, TYPE_WIRE_REQ_ID,
};
use bb_ir::{register_charged_bytes, register_type_node};
use crate::framework::Address;
use crate::ids::{CommandId, PeerId};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct TriggerValue;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct PeerIdValue(pub PeerId);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct PeerIdVecValue(pub Vec<PeerId>);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CommandIdValue(pub CommandId);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct TimestampValue(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct WireReqIdValue(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CorrelationTokenValue(pub u64);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AddressValue(pub Address);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AddressVecValue(pub Vec<Address>);
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BytesValue(pub Vec<u8>);
pub struct CompositeValue {
pub children: Vec<Box<dyn IrSlotValue>>,
}
impl Clone for CompositeValue {
fn clone(&self) -> Self {
Self {
children: self.children.iter().map(|c| c.clone_boxed()).collect(),
}
}
}
impl std::fmt::Debug for CompositeValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let hashes: Vec<u64> = self.children.iter().map(|c| c.type_hash()).collect();
f.debug_struct("CompositeValue")
.field("children_len", &self.children.len())
.field("child_type_hashes", &hashes)
.finish()
}
}
impl Serialize for CompositeValue {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
let mut seq = ser.serialize_seq(Some(self.children.len()))?;
for child in &self.children {
let bytes = child.to_wire_bytes().map_err(|e| {
serde::ser::Error::custom(format!("CompositeValue child encode: {e}"))
})?;
seq.serialize_element(&WireChild {
type_hash: child.type_hash(),
bytes,
})?;
}
seq.end()
}
}
impl<'de> Deserialize<'de> for CompositeValue {
fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
struct ChildrenVisitor;
impl<'de> Visitor<'de> for ChildrenVisitor {
type Value = Vec<Box<dyn IrSlotValue>>;
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "a sequence of (type_hash, bytes) child entries")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut out: Vec<Box<dyn IrSlotValue>> =
Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(entry) = seq.next_element::<WireChild>()? {
let decoder = wire_decoder_registry()
.get(&entry.type_hash)
.copied()
.ok_or_else(|| {
de::Error::custom(format!(
"CompositeValue child decode: no decoder registered for type_hash {:#018x}",
entry.type_hash,
))
})?;
let child = decoder(&entry.bytes).map_err(|e| {
de::Error::custom(format!("CompositeValue child decode: {e}"))
})?;
out.push(child);
}
Ok(out)
}
}
let children = de.deserialize_seq(ChildrenVisitor)?;
Ok(CompositeValue { children })
}
}
struct WireChild {
type_hash: u64,
bytes: Vec<u8>,
}
impl Serialize for WireChild {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
let mut t = ser.serialize_tuple(2)?;
t.serialize_element(&self.type_hash)?;
t.serialize_element(&self.bytes)?;
t.end()
}
}
impl<'de> Deserialize<'de> for WireChild {
fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
let (type_hash, bytes) = <(u64, Vec<u8>)>::deserialize(de)?;
Ok(WireChild { type_hash, bytes })
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct U64Value(pub u64);
register_type_node!(TriggerValue, &TYPE_TRIGGER);
register_type_node!(PeerIdValue, &TYPE_PEER_ID);
register_type_node!(PeerIdVecValue, &TYPE_PEER_ID_VEC);
register_type_node!(WireReqIdValue, &TYPE_WIRE_REQ_ID);
register_type_node!(BytesValue, &TYPE_BYTES);
register_type_node!(AddressValue, &TYPE_MULTIADDRESS);
register_type_node!(AddressVecValue, &TYPE_ADDRESS_VEC);
register_type_node!(CompositeValue, &TYPE_COMPOSITE);
register_charged_bytes!(BytesValue, |b: &BytesValue| b.0.len());