1mod conversion;
2#[cfg(feature = "random-identities")]
3pub mod random;
4
5#[cfg(feature = "json-conversion")]
6use crate::serialization::json_safe_fields;
7#[cfg(feature = "json-conversion")]
8use crate::serialization::JsonConvertible;
9#[cfg(feature = "value-conversion")]
10use crate::serialization::ValueConvertible;
11use std::collections::BTreeMap;
12#[cfg(feature = "value-conversion")]
13use std::convert::TryFrom;
14use std::hash::{Hash, Hasher};
15
16use crate::identity::{IdentityPublicKey, KeyID, PartialIdentity};
17use crate::prelude::Revision;
18#[cfg(feature = "value-conversion")]
19use platform_value::Value;
20
21#[cfg(feature = "value-conversion")]
22use crate::errors::ProtocolError;
23use crate::identifier::Identifier;
24#[cfg(feature = "identity-serialization")]
25use bincode::{Decode, Encode};
26
27#[cfg_attr(feature = "json-conversion", json_safe_fields)]
30#[derive(Default, Debug, Clone, Eq, PartialEq)]
31#[cfg_attr(feature = "identity-serialization", derive(Encode, Decode))]
32#[cfg_attr(
33 feature = "serde-conversion",
34 derive(serde::Serialize, serde::Deserialize),
35 serde(rename_all = "camelCase")
36)]
37#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
38pub struct IdentityV0 {
39 pub id: Identifier,
40 #[cfg_attr(feature = "serde-conversion", serde(with = "public_key_serialization"))]
41 pub public_keys: BTreeMap<KeyID, IdentityPublicKey>,
42 pub balance: u64,
43 pub revision: Revision,
44}
45
46impl Hash for IdentityV0 {
47 fn hash<H: Hasher>(&self, state: &mut H) {
48 self.id.hash(state);
49 }
50}
51
52#[cfg(all(feature = "json-conversion", feature = "serde-conversion"))]
53impl JsonConvertible for IdentityV0 {}
54
55mod public_key_serialization {
56 use crate::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0;
57 use crate::identity::{IdentityPublicKey, KeyID};
58 use serde::ser::SerializeSeq;
59 use serde::{Deserialize, Serializer};
60 use std::collections::BTreeMap;
61
62 pub fn deserialize<'de, D>(
64 deserializer: D,
65 ) -> Result<BTreeMap<KeyID, IdentityPublicKey>, D::Error>
66 where
67 D: serde::Deserializer<'de>,
68 {
69 let public_key_vec: Vec<IdentityPublicKey> = Deserialize::deserialize(deserializer)?;
70 Ok(public_key_vec.into_iter().map(|k| (k.id(), k)).collect())
71 }
72
73 pub fn serialize<S>(
74 public_keys: &BTreeMap<KeyID, IdentityPublicKey>,
75 serializer: S,
76 ) -> Result<S::Ok, S::Error>
77 where
78 S: Serializer,
79 {
80 let mut seq = serializer.serialize_seq(Some(public_keys.len()))?;
81 for element in public_keys.values() {
82 seq.serialize_element(element)?;
83 }
84 seq.end()
85 }
86}
87
88impl IdentityV0 {
89 pub fn get_feature_version(&self) -> u16 {
91 0
92 }
93
94 pub fn into_partial_identity_info(self) -> PartialIdentity {
96 let Self {
97 id,
98 public_keys,
99 balance,
100 revision,
101 ..
102 } = self;
103 PartialIdentity {
104 id,
105 loaded_public_keys: public_keys,
106 balance: Some(balance),
107 revision: Some(revision),
108 not_found_public_keys: Default::default(),
109 }
110 }
111
112 pub fn into_partial_identity_info_no_balance(self) -> PartialIdentity {
114 let Self {
115 id,
116 public_keys,
117 revision,
118 ..
119 } = self;
120 PartialIdentity {
121 id,
122 loaded_public_keys: public_keys,
123 balance: None,
124 revision: Some(revision),
125 not_found_public_keys: Default::default(),
126 }
127 }
128}
129
130#[cfg(feature = "value-conversion")]
131impl TryFrom<Value> for IdentityV0 {
132 type Error = ProtocolError;
133
134 fn try_from(value: Value) -> Result<Self, Self::Error> {
135 platform_value::from_value(value).map_err(ProtocolError::ValueError)
136 }
137}
138
139#[cfg(feature = "value-conversion")]
140impl TryFrom<&Value> for IdentityV0 {
141 type Error = ProtocolError;
142
143 fn try_from(value: &Value) -> Result<Self, Self::Error> {
144 platform_value::from_value(value.clone()).map_err(ProtocolError::ValueError)
145 }
146}
147
148#[cfg(all(
149 test,
150 feature = "json-conversion",
151 feature = "value-conversion",
152 feature = "serde-conversion"
153))]
154mod json_convertible_tests_identityv0 {
155 use super::*;
156
157 #[test]
158 fn json_round_trip_identityv0() {
159 use crate::serialization::JsonConvertible;
160 let original = IdentityV0::default();
161 let json = original.to_json().expect("to_json");
162 let recovered = IdentityV0::from_json(json).expect("from_json");
163 assert_eq!(original, recovered);
164 }
165
166 #[test]
167 fn value_round_trip_identityv0() {
168 use crate::serialization::ValueConvertible;
169 let original = IdentityV0::default();
170 let value = original.to_object().expect("to_object");
171 let recovered = IdentityV0::from_object(value).expect("from_object");
172 assert_eq!(original, recovered);
173 }
174}