amaru_kernel/cardano/
proposal_id.rs1use std::{cmp::Ordering, fmt, ops::Deref};
16
17pub use pallas_primitives::conway::GovActionId as ProposalId;
18
19use crate::cbor;
20
21#[derive(Debug, Eq, PartialEq, Clone)]
24#[repr(transparent)]
25pub struct ComparableProposalId {
26 pub inner: ProposalId,
27}
28
29impl ComparableProposalId {
30 pub fn to_compact_string(&self) -> String {
32 format!(
33 "{}.{}",
34 self.inner.action_index,
35 self.inner.transaction_id.to_string().chars().take(8).collect::<String>()
36 )
37 }
38}
39
40impl AsRef<ComparableProposalId> for ComparableProposalId {
41 fn as_ref(&self) -> &ComparableProposalId {
42 self
43 }
44}
45
46impl Deref for ComparableProposalId {
47 type Target = ProposalId;
48
49 fn deref(&self) -> &Self::Target {
50 &self.inner
51 }
52}
53
54impl fmt::Display for ComparableProposalId {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "{}#{}", self.inner.transaction_id, self.inner.action_index,)
57 }
58}
59
60impl From<ProposalId> for ComparableProposalId {
61 fn from(inner: ProposalId) -> Self {
62 Self { inner }
63 }
64}
65
66impl From<ComparableProposalId> for ProposalId {
67 fn from(comparable: ComparableProposalId) -> ProposalId {
68 comparable.inner
69 }
70}
71
72impl PartialOrd for ComparableProposalId {
73 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
74 Some(self.cmp(rhs))
75 }
76}
77
78impl Ord for ComparableProposalId {
79 fn cmp(&self, rhs: &Self) -> Ordering {
80 match self.inner.transaction_id.cmp(&rhs.inner.transaction_id) {
81 Ordering::Equal => self.inner.action_index.cmp(&rhs.inner.action_index),
82 ordering @ Ordering::Less | ordering @ Ordering::Greater => ordering,
83 }
84 }
85}
86
87impl<C> cbor::encode::Encode<C> for ComparableProposalId {
88 fn encode<W: cbor::encode::Write>(
89 &self,
90 e: &mut cbor::Encoder<W>,
91 ctx: &mut C,
92 ) -> Result<(), cbor::encode::Error<W::Error>> {
93 e.encode_with(&self.inner, ctx)?;
94 Ok(())
95 }
96}
97
98impl<'d, C> cbor::decode::Decode<'d, C> for ComparableProposalId {
99 fn decode(d: &mut cbor::Decoder<'d>, ctx: &mut C) -> Result<Self, cbor::decode::Error> {
100 Ok(Self { inner: d.decode_with(ctx)? })
101 }
102}
103
104#[cfg(any(test, feature = "test-utils"))]
105pub use tests::*;
106
107#[cfg(any(test, feature = "test-utils"))]
108mod tests {
109 use proptest::{prelude::*, prop_compose};
110
111 use super::{ComparableProposalId, ProposalId};
112 use crate::{Hash, prop_cbor_roundtrip};
113
114 prop_cbor_roundtrip!(ComparableProposalId, any_comparable_proposal_id());
115
116 prop_compose! {
117 pub fn any_proposal_id()(
118 transaction_id in any::<[u8; 32]>(),
119 action_index in any::<u32>(),
120 ) -> ProposalId {
121 ProposalId {
122 transaction_id: Hash::new(transaction_id),
123 action_index,
124 }
125 }
126 }
127
128 prop_compose! {
129 pub fn any_comparable_proposal_id()(
130 inner in any_proposal_id()
131 ) -> ComparableProposalId {
132 ComparableProposalId {
133 inner,
134 }
135 }
136 }
137}