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