Skip to main content

dpp/voting/vote_polls/
mod.rs

1#[cfg(feature = "json-conversion")]
2use crate::serialization::JsonConvertible;
3#[cfg(feature = "value-conversion")]
4use crate::serialization::ValueConvertible;
5use crate::voting::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePoll;
6use crate::voting::vote_polls::yes_no_vote_poll::YesNoVotePoll;
7use crate::ProtocolError;
8use bincode::{Decode, DecodeUntrusted, Encode};
9use derive_more::From;
10use platform_serialization_derive::{
11    PlatformDeserializeTrusted, PlatformDeserializeUntrusted, PlatformSerialize,
12};
13use platform_value::Identifier;
14use platform_version::version::PlatformVersion;
15#[cfg(feature = "serde-conversion")]
16use serde::{Deserialize, Serialize};
17use std::fmt;
18
19pub mod contested_document_resource_vote_poll;
20pub mod yes_no_vote_poll;
21
22#[cfg_attr(
23    all(feature = "json-conversion", feature = "serde-conversion"),
24    derive(JsonConvertible)
25)]
26#[derive(
27    Debug,
28    Clone,
29    Encode,
30    Decode,
31    PlatformSerialize,
32    PlatformDeserializeTrusted,
33    PlatformDeserializeUntrusted,
34    PartialEq,
35    From,
36    DecodeUntrusted,
37)]
38#[cfg_attr(
39    feature = "serde-conversion",
40    derive(Serialize, Deserialize),
41    // Internally tagged with a `$type` discriminator; inner
42    // `ContestedDocumentResourceVotePoll` fields flatten at the same level.
43    serde(tag = "$type", rename_all = "camelCase")
44)]
45#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
46#[platform_serialize(unversioned)]
47#[platform_serialize(limit = 100000)]
48pub enum VotePoll {
49    ContestedDocumentResourceVotePoll(ContestedDocumentResourceVotePoll),
50    /// A yes/no poll identified by its purpose, resolved by a supermajority once enough voting
51    /// power has been cast (protocol version 15). Its end date index entry carries it whole; a
52    /// vote names it by id. Appended: the bincode discriminant is the variant position.
53    YesNoVotePoll(YesNoVotePoll),
54}
55
56impl fmt::Display for VotePoll {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        match self {
59            VotePoll::ContestedDocumentResourceVotePoll(poll) => {
60                write!(f, "ContestedDocumentResourceVotePoll({})", poll)
61            }
62            VotePoll::YesNoVotePoll(poll) => write!(f, "YesNoVotePoll({})", poll),
63        }
64    }
65}
66
67impl Default for VotePoll {
68    fn default() -> Self {
69        ContestedDocumentResourceVotePoll::default().into()
70    }
71}
72
73impl VotePoll {
74    /// The prefunded balance the votes on this poll are paid from. A yes/no poll's id is
75    /// derived as the platform version selects; a contested poll's does not depend on it.
76    pub fn specialized_balance_id(
77        &self,
78        platform_version: &PlatformVersion,
79    ) -> Result<Option<Identifier>, ProtocolError> {
80        match self {
81            VotePoll::ContestedDocumentResourceVotePoll(contested_document_resource_vote_poll) => {
82                Ok(Some(
83                    contested_document_resource_vote_poll.specialized_balance_id()?,
84                ))
85            }
86            VotePoll::YesNoVotePoll(yes_no_vote_poll) => Ok(Some(
87                yes_no_vote_poll.specialized_balance_id(platform_version)?,
88            )),
89        }
90    }
91
92    /// The id the poll is stored and voted on under. A yes/no poll's id is derived as the
93    /// platform version selects; a contested poll's does not depend on it.
94    pub fn unique_id(
95        &self,
96        platform_version: &PlatformVersion,
97    ) -> Result<Identifier, ProtocolError> {
98        match self {
99            VotePoll::ContestedDocumentResourceVotePoll(contested_document_resource_vote_poll) => {
100                contested_document_resource_vote_poll.unique_id()
101            }
102            VotePoll::YesNoVotePoll(yes_no_vote_poll) => {
103                yes_no_vote_poll.unique_id(platform_version)
104            }
105        }
106    }
107}
108
109#[cfg(all(
110    test,
111    feature = "json-conversion",
112    feature = "value-conversion",
113    feature = "serde-conversion"
114))]
115mod json_convertible_tests_votepoll {
116    use super::*;
117
118    #[test]
119    fn json_round_trip_votepoll() {
120        use crate::serialization::JsonConvertible;
121        let original = VotePoll::default();
122        let json = original.to_json().expect("to_json");
123        let recovered = VotePoll::from_json(json).expect("from_json");
124        assert_eq!(original, recovered);
125    }
126
127    #[test]
128    fn value_round_trip_votepoll() {
129        use crate::serialization::ValueConvertible;
130        let original = VotePoll::default();
131        let value = original.to_object().expect("to_object");
132        let recovered = VotePoll::from_object(value).expect("from_object");
133        assert_eq!(original, recovered);
134    }
135}