dpp/voting/votes/resource_vote/v0/
mod.rs1#[cfg(feature = "json-conversion")]
2use crate::serialization::json_safe_fields;
3use crate::voting::vote_choices::resource_vote_choice::ResourceVoteChoice;
4use crate::voting::vote_polls::VotePoll;
5use crate::ProtocolError;
6use bincode::{Decode, DecodeUntrusted, Encode};
7use platform_serialization_derive::{
8 PlatformDeserializeTrusted, PlatformDeserializeUntrusted, PlatformSerialize,
9};
10use platform_value::Identifier;
11use platform_version::version::PlatformVersion;
12#[cfg(feature = "serde-conversion")]
13use serde::{Deserialize, Serialize};
14
15#[cfg_attr(feature = "json-conversion", json_safe_fields)]
16#[derive(
17 Debug,
18 Clone,
19 Encode,
20 Decode,
21 PlatformDeserializeTrusted,
22 PlatformDeserializeUntrusted,
23 PlatformSerialize,
24 PartialEq,
25 DecodeUntrusted,
26)]
27#[cfg_attr(
28 feature = "serde-conversion",
29 derive(Serialize, Deserialize),
30 serde(rename_all = "camelCase"),
31 serde(try_from = "ResourceVoteV0Inner")
32)]
33#[platform_serialize(unversioned)]
34pub struct ResourceVoteV0 {
35 pub vote_poll: VotePoll,
36 pub resource_vote_choice: ResourceVoteChoice,
37}
38
39#[cfg(feature = "serde-conversion")]
42#[derive(Deserialize)]
43#[serde(rename_all = "camelCase")]
44struct ResourceVoteV0Inner {
45 vote_poll: VotePoll,
46 resource_vote_choice: ResourceVoteChoice,
47}
48
49#[cfg(feature = "serde-conversion")]
50impl TryFrom<ResourceVoteV0Inner> for ResourceVoteV0 {
51 type Error = ProtocolError;
52
53 fn try_from(value: ResourceVoteV0Inner) -> Result<Self, Self::Error> {
54 ResourceVoteV0::try_new(value.vote_poll, value.resource_vote_choice)
55 }
56}
57
58impl Default for ResourceVoteV0 {
59 fn default() -> Self {
60 ResourceVoteV0 {
61 vote_poll: VotePoll::default(),
62 resource_vote_choice: ResourceVoteChoice::Abstain,
63 }
64 }
65}
66
67impl ResourceVoteV0 {
68 pub fn try_new(
72 vote_poll: VotePoll,
73 resource_vote_choice: ResourceVoteChoice,
74 ) -> Result<Self, ProtocolError> {
75 match vote_poll {
76 VotePoll::ContestedDocumentResourceVotePoll(_) => Ok(ResourceVoteV0 {
77 vote_poll,
78 resource_vote_choice,
79 }),
80 VotePoll::YesNoVotePoll(_) => Err(ProtocolError::VoteError(
81 "a resource vote answers a contested document resource vote poll; a yes/no vote \
82 poll is answered by a yes/no vote"
83 .to_string(),
84 )),
85 }
86 }
87
88 pub fn vote_poll_unique_id(
90 &self,
91 platform_version: &PlatformVersion,
92 ) -> Result<Identifier, ProtocolError> {
93 self.vote_poll.unique_id(platform_version)
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::voting::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePoll;
101 use crate::voting::vote_polls::yes_no_vote_poll::{
102 YesNoMinimumVotingPower, YesNoVotePoll, YesNoVotePollPurpose,
103 };
104 use platform_value::Identifier;
105
106 #[test]
107 fn should_build_a_resource_vote_only_on_a_contested_poll() {
108 let contested_poll = VotePoll::ContestedDocumentResourceVotePoll(
109 ContestedDocumentResourceVotePoll::default(),
110 );
111 let vote = ResourceVoteV0::try_new(contested_poll.clone(), ResourceVoteChoice::Abstain)
112 .expect("expected a resource vote on a contested poll");
113 assert_eq!(vote.vote_poll, contested_poll);
114
115 let yes_no_poll = VotePoll::YesNoVotePoll(YesNoVotePoll {
116 purpose: YesNoVotePollPurpose::DecisionProposal {
117 document_id: Identifier::new([0xc1; 32]),
118 },
119 supermajority_numerator: 2,
120 supermajority_denominator: 3,
121 minimum_voting_power: YesNoMinimumVotingPower::Absolute { voting_power: 0 },
122 });
123 ResourceVoteV0::try_new(yes_no_poll, ResourceVoteChoice::Abstain)
124 .expect_err("expected a resource vote on a yes/no poll to be refused");
125 }
126}