Skip to main content

dpp/voting/votes/
mod.rs

1pub mod resource_vote;
2
3#[cfg(feature = "json-conversion")]
4use crate::serialization::JsonConvertible;
5#[cfg(feature = "value-conversion")]
6use crate::serialization::ValueConvertible;
7use crate::voting::votes::resource_vote::accessors::v0::ResourceVoteGettersV0;
8use crate::voting::votes::resource_vote::ResourceVote;
9use crate::ProtocolError;
10use bincode::{Decode, DecodeUntrusted, Encode};
11use derive_more::From;
12use platform_serialization_derive::{
13    PlatformDeserializeTrusted, PlatformDeserializeUntrusted, PlatformSerialize,
14};
15use platform_value::Identifier;
16#[cfg(feature = "serde-conversion")]
17use serde::{Deserialize, Serialize};
18
19#[derive(
20    Debug,
21    Clone,
22    Encode,
23    Decode,
24    PlatformSerialize,
25    PlatformDeserializeTrusted,
26    PlatformDeserializeUntrusted,
27    PartialEq,
28    From,
29    DecodeUntrusted,
30)]
31#[cfg_attr(
32    feature = "serde-conversion",
33    derive(Serialize, Deserialize),
34    // Internal tagging with `$type` — system-field convention. Drops the
35    // `data` wrapper. Inner `ResourceVote` is `tag = "$formatVersion"`
36    // (different key, no collision).
37    serde(tag = "$type", rename_all = "camelCase")
38)]
39#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
40#[platform_serialize(limit = 15000, unversioned)]
41pub enum Vote {
42    ResourceVote(ResourceVote),
43}
44
45// Manual impl because Vote is a flat enum (not versioned V0/V1).
46#[cfg(feature = "json-conversion")]
47impl JsonConvertible for Vote {}
48
49impl Default for Vote {
50    fn default() -> Self {
51        Vote::ResourceVote(ResourceVote::default())
52    }
53}
54
55impl Vote {
56    pub fn specialized_balance_id(&self) -> Result<Option<Identifier>, ProtocolError> {
57        match self {
58            Vote::ResourceVote(resource_vote) => resource_vote.vote_poll().specialized_balance_id(),
59        }
60    }
61    pub fn vote_poll_unique_id(&self) -> Result<Identifier, ProtocolError> {
62        match self {
63            Vote::ResourceVote(resource_vote) => resource_vote.vote_poll().unique_id(),
64        }
65    }
66}
67
68#[cfg(all(test, feature = "json-conversion"))]
69mod tests {
70    use super::*;
71    use crate::serialization::JsonConvertible;
72    use crate::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
73    use crate::voting::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePoll;
74    use crate::voting::vote_polls::VotePoll;
75    use crate::voting::votes::resource_vote::v0::ResourceVoteV0;
76    use crate::voting::votes::resource_vote::ResourceVote;
77
78    #[test]
79    fn vote_json_round_trip() {
80        let contract_id = Identifier::from([0x11u8; 32]);
81        let towards_id = Identifier::from([0x22u8; 32]);
82
83        let vote = Vote::ResourceVote(ResourceVote::V0(ResourceVoteV0 {
84            vote_poll: VotePoll::ContestedDocumentResourceVotePoll(
85                ContestedDocumentResourceVotePoll {
86                    contract_id,
87                    document_type_name: "domain".to_string(),
88                    index_name: "parentNameAndLabel".to_string(),
89                    index_values: vec![platform_value::Value::Text("dash".to_string())],
90                },
91            ),
92            resource_vote_choice: ResourceVoteChoice::TowardsIdentity(towards_id),
93        }));
94
95        let json = vote.to_json().expect("to_json should succeed");
96
97        // Verify it's a valid JSON object
98        assert!(json.is_object(), "Vote JSON should be an object");
99
100        // round-trip
101        let restored = Vote::from_json(json).expect("from_json should succeed");
102        assert_eq!(vote, restored);
103    }
104}
105
106#[cfg(all(
107    test,
108    feature = "json-conversion",
109    feature = "value-conversion",
110    feature = "serde-conversion"
111))]
112mod json_convertible_tests_vote {
113    use super::*;
114
115    #[test]
116    fn json_round_trip_vote() {
117        use crate::serialization::JsonConvertible;
118        let original = Vote::default();
119        let json = original.to_json().expect("to_json");
120        let recovered = Vote::from_json(json).expect("from_json");
121        assert_eq!(original, recovered);
122    }
123
124    #[test]
125    fn value_round_trip_vote() {
126        use crate::serialization::ValueConvertible;
127        let original = Vote::default();
128        let value = original.to_object().expect("to_object");
129        let recovered = Vote::from_object(value).expect("from_object");
130        assert_eq!(original, recovered);
131    }
132}