dpp/voting/vote_choices/resource_vote_choice/
mod.rs1#[cfg(feature = "json-conversion")]
2use crate::serialization::JsonConvertible;
3#[cfg(feature = "value-conversion")]
4use crate::serialization::ValueConvertible;
5use crate::voting::vote_choices::resource_vote_choice::ResourceVoteChoice::{
6 Abstain, Lock, TowardsIdentity,
7};
8use crate::ProtocolError;
9use bincode::{Decode, Encode};
10use platform_value::Identifier;
11#[cfg(feature = "serde-conversion")]
12use serde::{Deserialize, Serialize};
13use std::fmt;
14
15#[derive(Debug, Clone, Copy, Encode, Decode, Ord, Eq, PartialOrd, PartialEq, Default)]
25#[cfg_attr(
26 feature = "serde-conversion",
27 derive(Serialize, Deserialize),
28 serde(tag = "type", content = "data", rename_all = "camelCase")
29)]
30#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
31pub enum ResourceVoteChoice {
32 TowardsIdentity(Identifier),
33 #[default]
34 Abstain,
35 Lock,
36}
37
38impl fmt::Display for ResourceVoteChoice {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 ResourceVoteChoice::TowardsIdentity(identifier) => {
42 write!(f, "TowardsIdentity({})", identifier)
43 }
44 ResourceVoteChoice::Abstain => write!(f, "Abstain"),
45 ResourceVoteChoice::Lock => write!(f, "Lock"),
46 }
47 }
48}
49
50#[cfg(feature = "json-conversion")]
52impl JsonConvertible for ResourceVoteChoice {}
53
54#[cfg(all(test, feature = "json-conversion"))]
55mod tests {
56 use super::*;
57 use crate::serialization::JsonConvertible;
58
59 #[test]
60 fn resource_vote_choice_towards_identity_json_round_trip() {
61 let id = Identifier::from([0x42u8; 32]);
62 let choice = ResourceVoteChoice::TowardsIdentity(id);
63
64 let json = choice.to_json().expect("to_json should succeed");
65 let json_str = serde_json::to_string(&json).unwrap();
66 let expected_base58 = id.to_string(platform_value::string_encoding::Encoding::Base58);
67 assert!(
68 json_str.contains(&expected_base58),
69 "JSON should contain base58 identifier {}, got: {}",
70 expected_base58,
71 json_str
72 );
73
74 let restored = ResourceVoteChoice::from_json(json).expect("from_json should succeed");
75 assert_eq!(choice, restored);
76 }
77
78 #[test]
79 fn resource_vote_choice_abstain_json_round_trip() {
80 let choice = ResourceVoteChoice::Abstain;
81 let json = choice.to_json().expect("to_json should succeed");
82 let restored = ResourceVoteChoice::from_json(json).expect("from_json should succeed");
83 assert_eq!(choice, restored);
84 }
85
86 #[test]
87 fn resource_vote_choice_lock_json_round_trip() {
88 let choice = ResourceVoteChoice::Lock;
89 let json = choice.to_json().expect("to_json should succeed");
90 let restored = ResourceVoteChoice::from_json(json).expect("from_json should succeed");
91 assert_eq!(choice, restored);
92 }
93}
94
95impl TryFrom<(i32, Option<Vec<u8>>)> for ResourceVoteChoice {
96 type Error = ProtocolError;
97
98 fn try_from(value: (i32, Option<Vec<u8>>)) -> Result<Self, Self::Error> {
99 match value.0 {
100 0 => Ok(TowardsIdentity(value.1.ok_or(ProtocolError::DecodingError("identifier needed when trying to cast from an i32 to a resource vote choice".to_string()))?.try_into()?)),
101 1 => Ok(Abstain),
102 2 => Ok(Lock),
103 n => Err(ProtocolError::DecodingError(format!("identifier must be 0, 1, or 2, got {}", n)))
104 }
105 }
106}