grid_sdk/protocol/pike/
state.rs

1// Copyright 2019-2021 Cargill Incorporated
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Protocol structs for Pike state
16
17use protobuf::Message;
18use protobuf::RepeatedField;
19
20use std::error::Error as StdError;
21
22use crate::protos;
23use crate::protos::{
24    FromBytes, FromNative, FromProto, IntoBytes, IntoNative, IntoProto, ProtoConversionError,
25};
26
27/// Native representation of a `KeyValueEntry`
28///
29/// A `KeyValueEntry` organizes additional data, `metadata`, for state objects. Any data,
30/// represented as a `String`, may be stored within a `KeyValueEntry`.
31#[derive(Debug, Clone, PartialEq)]
32pub struct KeyValueEntry {
33    key: String,
34    value: String,
35}
36
37impl KeyValueEntry {
38    pub fn key(&self) -> &str {
39        &self.key
40    }
41
42    pub fn value(&self) -> &str {
43        &self.value
44    }
45}
46
47impl FromProto<protos::pike_state::KeyValueEntry> for KeyValueEntry {
48    fn from_proto(
49        key_value: protos::pike_state::KeyValueEntry,
50    ) -> Result<Self, ProtoConversionError> {
51        Ok(KeyValueEntry {
52            key: key_value.get_key().to_string(),
53            value: key_value.get_value().to_string(),
54        })
55    }
56}
57
58impl FromNative<KeyValueEntry> for protos::pike_state::KeyValueEntry {
59    fn from_native(key_value: KeyValueEntry) -> Result<Self, ProtoConversionError> {
60        let mut key_value_proto = protos::pike_state::KeyValueEntry::new();
61
62        key_value_proto.set_key(key_value.key().to_string());
63        key_value_proto.set_value(key_value.value().to_string());
64
65        Ok(key_value_proto)
66    }
67}
68
69impl FromBytes<KeyValueEntry> for KeyValueEntry {
70    fn from_bytes(bytes: &[u8]) -> Result<KeyValueEntry, ProtoConversionError> {
71        let proto: protos::pike_state::KeyValueEntry =
72            Message::parse_from_bytes(bytes).map_err(|_| {
73                ProtoConversionError::SerializationError(
74                    "Unable to get KeyValueEntry from bytes".to_string(),
75                )
76            })?;
77        proto.into_native()
78    }
79}
80
81impl IntoBytes for KeyValueEntry {
82    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
83        let proto = self.into_proto()?;
84        let bytes = proto.write_to_bytes().map_err(|_| {
85            ProtoConversionError::SerializationError(
86                "Unable to get bytes from KeyValueEntry".to_string(),
87            )
88        })?;
89        Ok(bytes)
90    }
91}
92
93impl IntoProto<protos::pike_state::KeyValueEntry> for KeyValueEntry {}
94impl IntoNative<KeyValueEntry> for protos::pike_state::KeyValueEntry {}
95
96/// Returned if any required fields in a `KeyValueEntry` are not present when being
97/// converted from the corresponding builder
98#[derive(Debug)]
99pub enum KeyValueEntryBuildError {
100    MissingField(String),
101}
102
103impl StdError for KeyValueEntryBuildError {
104    fn description(&self) -> &str {
105        match *self {
106            KeyValueEntryBuildError::MissingField(ref msg) => msg,
107        }
108    }
109
110    fn cause(&self) -> Option<&dyn StdError> {
111        match *self {
112            KeyValueEntryBuildError::MissingField(_) => None,
113        }
114    }
115}
116
117impl std::fmt::Display for KeyValueEntryBuildError {
118    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
119        match *self {
120            KeyValueEntryBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
121        }
122    }
123}
124
125/// Builder used to create a `KeyValueEntry`
126#[derive(Default, Clone)]
127pub struct KeyValueEntryBuilder {
128    pub key: Option<String>,
129    pub value: Option<String>,
130}
131
132impl KeyValueEntryBuilder {
133    pub fn new() -> Self {
134        KeyValueEntryBuilder::default()
135    }
136
137    pub fn with_key(mut self, key: String) -> KeyValueEntryBuilder {
138        self.key = Some(key);
139        self
140    }
141
142    pub fn with_value(mut self, value: String) -> KeyValueEntryBuilder {
143        self.value = Some(value);
144        self
145    }
146
147    pub fn build(self) -> Result<KeyValueEntry, KeyValueEntryBuildError> {
148        let key = self.key.ok_or_else(|| {
149            KeyValueEntryBuildError::MissingField("'key' field is required".to_string())
150        })?;
151
152        let value = self.value.ok_or_else(|| {
153            KeyValueEntryBuildError::MissingField("'value' field is required".to_string())
154        })?;
155
156        Ok(KeyValueEntry { key, value })
157    }
158}
159
160/// Native representation of a `Role`
161///
162/// A `Role` defines the permissions that are able to be assigned to an `Organization`'s `Agent`.
163/// This allows agents to perform actions defined within their role.
164#[derive(Debug, Clone, PartialEq)]
165pub struct Role {
166    org_id: String,
167    name: String,
168    description: String,
169    active: bool,
170    permissions: Vec<String>,
171    allowed_organizations: Vec<String>,
172    inherit_from: Vec<String>,
173}
174
175impl Role {
176    pub fn org_id(&self) -> &str {
177        &self.org_id
178    }
179
180    pub fn name(&self) -> &str {
181        &self.name
182    }
183
184    pub fn description(&self) -> &str {
185        &self.description
186    }
187
188    pub fn active(&self) -> &bool {
189        &self.active
190    }
191
192    pub fn permissions(&self) -> &[String] {
193        &self.permissions
194    }
195
196    pub fn allowed_organizations(&self) -> &[String] {
197        &self.allowed_organizations
198    }
199
200    pub fn inherit_from(&self) -> &[String] {
201        &self.inherit_from
202    }
203}
204
205impl FromProto<protos::pike_state::Role> for Role {
206    fn from_proto(role: protos::pike_state::Role) -> Result<Self, ProtoConversionError> {
207        Ok(Role {
208            org_id: role.get_org_id().to_string(),
209            name: role.get_name().to_string(),
210            description: role.get_description().to_string(),
211            active: role.get_active(),
212            permissions: role.get_permissions().to_vec(),
213            allowed_organizations: role.get_allowed_organizations().to_vec(),
214            inherit_from: role.get_inherit_from().to_vec(),
215        })
216    }
217}
218
219impl FromNative<Role> for protos::pike_state::Role {
220    fn from_native(role: Role) -> Result<Self, ProtoConversionError> {
221        let mut role_proto = protos::pike_state::Role::new();
222
223        role_proto.set_org_id(role.org_id().to_string());
224        role_proto.set_name(role.name().to_string());
225        role_proto.set_description(role.description().to_string());
226        role_proto.set_active(*role.active());
227        role_proto.set_permissions(RepeatedField::from_vec(role.permissions().to_vec()));
228        role_proto.set_allowed_organizations(RepeatedField::from_vec(
229            role.allowed_organizations().to_vec(),
230        ));
231        role_proto.set_inherit_from(RepeatedField::from_vec(role.inherit_from().to_vec()));
232
233        Ok(role_proto)
234    }
235}
236
237impl FromBytes<Role> for Role {
238    fn from_bytes(bytes: &[u8]) -> Result<Role, ProtoConversionError> {
239        let proto: protos::pike_state::Role = Message::parse_from_bytes(bytes).map_err(|_| {
240            ProtoConversionError::SerializationError("Unable to get Role from bytes".to_string())
241        })?;
242        proto.into_native()
243    }
244}
245
246impl IntoBytes for Role {
247    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
248        let proto = self.into_proto()?;
249        let bytes = proto.write_to_bytes().map_err(|_| {
250            ProtoConversionError::SerializationError("Unable to get bytes from Role".to_string())
251        })?;
252        Ok(bytes)
253    }
254}
255
256impl IntoProto<protos::pike_state::Role> for Role {}
257impl IntoNative<Role> for protos::pike_state::Role {}
258
259/// Returned if any required fields in a `Role` are not present when being
260/// converted from the corresponding builder
261#[derive(Debug)]
262pub enum RoleBuildError {
263    MissingField(String),
264}
265
266impl StdError for RoleBuildError {
267    fn description(&self) -> &str {
268        match *self {
269            RoleBuildError::MissingField(ref msg) => msg,
270        }
271    }
272
273    fn cause(&self) -> Option<&dyn StdError> {
274        match *self {
275            RoleBuildError::MissingField(_) => None,
276        }
277    }
278}
279
280impl std::fmt::Display for RoleBuildError {
281    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
282        match *self {
283            RoleBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
284        }
285    }
286}
287
288/// Builder used to create a `Role`
289#[derive(Default, Clone)]
290pub struct RoleBuilder {
291    org_id: Option<String>,
292    name: Option<String>,
293    description: Option<String>,
294    active: bool,
295    permissions: Vec<String>,
296    allowed_organizations: Vec<String>,
297    inherit_from: Vec<String>,
298}
299
300impl RoleBuilder {
301    pub fn new() -> Self {
302        RoleBuilder::default()
303    }
304
305    pub fn with_org_id(mut self, org_id: String) -> RoleBuilder {
306        self.org_id = Some(org_id);
307        self
308    }
309
310    pub fn with_name(mut self, name: String) -> RoleBuilder {
311        self.name = Some(name);
312        self
313    }
314
315    pub fn with_description(mut self, description: String) -> RoleBuilder {
316        self.description = Some(description);
317        self
318    }
319
320    pub fn with_active(mut self, active: bool) -> RoleBuilder {
321        self.active = active;
322        self
323    }
324
325    pub fn with_permissions(mut self, permissions: Vec<String>) -> RoleBuilder {
326        self.permissions = permissions;
327        self
328    }
329
330    pub fn with_allowed_organizations(mut self, allowed_organizations: Vec<String>) -> RoleBuilder {
331        self.allowed_organizations = allowed_organizations;
332        self
333    }
334
335    pub fn with_inherit_from(mut self, inherit_from: Vec<String>) -> RoleBuilder {
336        self.inherit_from = inherit_from;
337        self
338    }
339
340    pub fn build(self) -> Result<Role, RoleBuildError> {
341        let org_id = self.org_id.ok_or_else(|| {
342            RoleBuildError::MissingField("'org_id' field is required".to_string())
343        })?;
344
345        let name = self
346            .name
347            .ok_or_else(|| RoleBuildError::MissingField("'name' field is required".to_string()))?;
348
349        let description = self.description.unwrap_or_else(|| "".to_string());
350
351        let active = self.active;
352
353        let permissions = self.permissions;
354        let allowed_organizations = self.allowed_organizations;
355        let inherit_from = self.inherit_from;
356
357        Ok(Role {
358            org_id,
359            name,
360            description,
361            active,
362            permissions,
363            allowed_organizations,
364            inherit_from,
365        })
366    }
367}
368
369/// Native representation of a list of `Role`s
370#[derive(Debug, Clone, PartialEq)]
371pub struct RoleList {
372    roles: Vec<Role>,
373}
374
375impl RoleList {
376    pub fn roles(&self) -> &[Role] {
377        &self.roles
378    }
379}
380
381impl FromProto<protos::pike_state::RoleList> for RoleList {
382    fn from_proto(role_list: protos::pike_state::RoleList) -> Result<Self, ProtoConversionError> {
383        Ok(RoleList {
384            roles: role_list
385                .get_roles()
386                .iter()
387                .cloned()
388                .map(Role::from_proto)
389                .collect::<Result<Vec<Role>, ProtoConversionError>>()?,
390        })
391    }
392}
393
394impl FromNative<RoleList> for protos::pike_state::RoleList {
395    fn from_native(role_list: RoleList) -> Result<Self, ProtoConversionError> {
396        let mut role_list_proto = protos::pike_state::RoleList::new();
397
398        role_list_proto.set_roles(RepeatedField::from_vec(
399            role_list
400                .roles()
401                .iter()
402                .cloned()
403                .map(Role::into_proto)
404                .collect::<Result<Vec<protos::pike_state::Role>, ProtoConversionError>>()?,
405        ));
406
407        Ok(role_list_proto)
408    }
409}
410
411impl FromBytes<RoleList> for RoleList {
412    fn from_bytes(bytes: &[u8]) -> Result<RoleList, ProtoConversionError> {
413        let proto: protos::pike_state::RoleList =
414            Message::parse_from_bytes(bytes).map_err(|_| {
415                ProtoConversionError::SerializationError(
416                    "Unable to get RoleList from bytes".to_string(),
417                )
418            })?;
419
420        proto.into_native()
421    }
422}
423
424impl IntoBytes for RoleList {
425    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
426        let proto = self.into_proto()?;
427        let bytes = proto.write_to_bytes().map_err(|_| {
428            ProtoConversionError::SerializationError(
429                "Unable to get bytes from RoleList".to_string(),
430            )
431        })?;
432        Ok(bytes)
433    }
434}
435
436impl IntoProto<protos::pike_state::RoleList> for RoleList {}
437impl IntoNative<RoleList> for protos::pike_state::RoleList {}
438
439/// Returned if any required fields in a `RoleList` are not present when being
440/// converted from the corresponding builder
441#[derive(Debug)]
442pub enum RoleListBuildError {
443    MissingField(String),
444}
445
446impl StdError for RoleListBuildError {
447    fn description(&self) -> &str {
448        match *self {
449            RoleListBuildError::MissingField(ref msg) => msg,
450        }
451    }
452
453    fn cause(&self) -> Option<&dyn StdError> {
454        match *self {
455            RoleListBuildError::MissingField(_) => None,
456        }
457    }
458}
459
460impl std::fmt::Display for RoleListBuildError {
461    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
462        match *self {
463            RoleListBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
464        }
465    }
466}
467
468/// Builder used to create a `RoleList`
469#[derive(Default, Clone)]
470pub struct RoleListBuilder {
471    pub roles: Vec<Role>,
472}
473
474impl RoleListBuilder {
475    pub fn new() -> Self {
476        RoleListBuilder::default()
477    }
478
479    pub fn with_roles(mut self, roles: Vec<Role>) -> RoleListBuilder {
480        self.roles = roles;
481        self
482    }
483
484    pub fn build(self) -> Result<RoleList, RoleListBuildError> {
485        let roles = {
486            if self.roles.is_empty() {
487                return Err(RoleListBuildError::MissingField(
488                    "'roles' cannot be empty".to_string(),
489                ));
490            } else {
491                self.roles
492            }
493        };
494
495        Ok(RoleList { roles })
496    }
497}
498
499/// Native representation of the state object `AlternateIdIndexEntry`
500///
501/// The `AlternateIdIndexEntry` serves as an index to fetch an `Organization` from an externally
502/// known ID and ensures the alternate ID is unique to the owning organization.
503#[derive(Debug, Clone, PartialEq)]
504pub struct AlternateIdIndexEntry {
505    id_type: String,
506    id: String,
507    grid_identity_id: String,
508}
509
510impl AlternateIdIndexEntry {
511    pub fn id_type(&self) -> &str {
512        &self.id_type
513    }
514
515    pub fn id(&self) -> &str {
516        &self.id
517    }
518
519    pub fn grid_identity_id(&self) -> &str {
520        &self.grid_identity_id
521    }
522}
523
524impl FromProto<protos::pike_state::AlternateIdIndexEntry> for AlternateIdIndexEntry {
525    fn from_proto(
526        id: protos::pike_state::AlternateIdIndexEntry,
527    ) -> Result<Self, ProtoConversionError> {
528        Ok(AlternateIdIndexEntry {
529            id_type: id.get_id_type().to_string(),
530            id: id.get_id().to_string(),
531            grid_identity_id: id.get_grid_identity_id().to_string(),
532        })
533    }
534}
535
536impl FromNative<AlternateIdIndexEntry> for protos::pike_state::AlternateIdIndexEntry {
537    fn from_native(id: AlternateIdIndexEntry) -> Result<Self, ProtoConversionError> {
538        let mut alt_id_proto = protos::pike_state::AlternateIdIndexEntry::new();
539
540        alt_id_proto.set_id_type(id.id_type().to_string());
541        alt_id_proto.set_id(id.id().to_string());
542        alt_id_proto.set_grid_identity_id(id.grid_identity_id().to_string());
543
544        Ok(alt_id_proto)
545    }
546}
547
548impl FromBytes<AlternateIdIndexEntry> for AlternateIdIndexEntry {
549    fn from_bytes(bytes: &[u8]) -> Result<AlternateIdIndexEntry, ProtoConversionError> {
550        let proto: protos::pike_state::AlternateIdIndexEntry = Message::parse_from_bytes(bytes)
551            .map_err(|_| {
552                ProtoConversionError::SerializationError(
553                    "Unable to get AlternateIdIndexEntry from bytes".to_string(),
554                )
555            })?;
556        proto.into_native()
557    }
558}
559
560impl IntoBytes for AlternateIdIndexEntry {
561    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
562        let proto = self.into_proto()?;
563        let bytes = proto.write_to_bytes().map_err(|_| {
564            ProtoConversionError::SerializationError(
565                "Unable to get bytes from AlternateIdIndexEntry".to_string(),
566            )
567        })?;
568        Ok(bytes)
569    }
570}
571
572impl IntoProto<protos::pike_state::AlternateIdIndexEntry> for AlternateIdIndexEntry {}
573impl IntoNative<AlternateIdIndexEntry> for protos::pike_state::AlternateIdIndexEntry {}
574
575/// Returned if any required fields in an `AlternateIdIndexEntry` are not present when being
576/// converted from the corresponding builder
577#[derive(Debug)]
578pub enum AlternateIdIndexEntryBuildError {
579    MissingField(String),
580}
581
582impl StdError for AlternateIdIndexEntryBuildError {
583    fn description(&self) -> &str {
584        match *self {
585            AlternateIdIndexEntryBuildError::MissingField(ref msg) => msg,
586        }
587    }
588
589    fn cause(&self) -> Option<&dyn StdError> {
590        match *self {
591            AlternateIdIndexEntryBuildError::MissingField(_) => None,
592        }
593    }
594}
595
596impl std::fmt::Display for AlternateIdIndexEntryBuildError {
597    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
598        match *self {
599            AlternateIdIndexEntryBuildError::MissingField(ref s) => {
600                write!(f, "MissingField: {}", s)
601            }
602        }
603    }
604}
605
606/// Builder used to create an `AlternateIdIndexEntry`
607#[derive(Default, Clone)]
608pub struct AlternateIdIndexEntryBuilder {
609    pub id_type: Option<String>,
610    pub id: Option<String>,
611    pub grid_identity_id: Option<String>,
612}
613
614impl AlternateIdIndexEntryBuilder {
615    pub fn new() -> Self {
616        AlternateIdIndexEntryBuilder::default()
617    }
618
619    pub fn with_id_type(mut self, id_type: String) -> AlternateIdIndexEntryBuilder {
620        self.id_type = Some(id_type);
621        self
622    }
623
624    pub fn with_id(mut self, id: String) -> AlternateIdIndexEntryBuilder {
625        self.id = Some(id);
626        self
627    }
628
629    pub fn with_grid_identity_id(
630        mut self,
631        grid_identity_id: String,
632    ) -> AlternateIdIndexEntryBuilder {
633        self.grid_identity_id = Some(grid_identity_id);
634        self
635    }
636
637    pub fn build(self) -> Result<AlternateIdIndexEntry, AlternateIdIndexEntryBuildError> {
638        let id_type = self.id_type.ok_or_else(|| {
639            AlternateIdIndexEntryBuildError::MissingField("'id_type' field is required".to_string())
640        })?;
641
642        let id = self.id.ok_or_else(|| {
643            AlternateIdIndexEntryBuildError::MissingField("'id' field is required".to_string())
644        })?;
645
646        let grid_identity_id = self.grid_identity_id.ok_or_else(|| {
647            AlternateIdIndexEntryBuildError::MissingField(
648                "'grid_identity_id' field is required".to_string(),
649            )
650        })?;
651
652        Ok(AlternateIdIndexEntry {
653            id_type,
654            id,
655            grid_identity_id,
656        })
657    }
658}
659
660/// Native representation of a list of `AlternateIdIndexEntry`s
661#[derive(Debug, Clone, PartialEq)]
662pub struct AlternateIdIndexEntryList {
663    entries: Vec<AlternateIdIndexEntry>,
664}
665
666impl AlternateIdIndexEntryList {
667    pub fn entries(&self) -> &[AlternateIdIndexEntry] {
668        &self.entries
669    }
670}
671
672impl FromProto<protos::pike_state::AlternateIdIndexEntryList> for AlternateIdIndexEntryList {
673    fn from_proto(
674        entry_list: protos::pike_state::AlternateIdIndexEntryList,
675    ) -> Result<Self, ProtoConversionError> {
676        Ok(AlternateIdIndexEntryList {
677            entries: entry_list
678                .get_entries()
679                .iter()
680                .cloned()
681                .map(AlternateIdIndexEntry::from_proto)
682                .collect::<Result<Vec<AlternateIdIndexEntry>, ProtoConversionError>>()?,
683        })
684    }
685}
686
687impl FromNative<AlternateIdIndexEntryList> for protos::pike_state::AlternateIdIndexEntryList {
688    fn from_native(entry_list: AlternateIdIndexEntryList) -> Result<Self, ProtoConversionError> {
689        let mut entry_list_proto = protos::pike_state::AlternateIdIndexEntryList::new();
690
691        entry_list_proto.set_entries(RepeatedField::from_vec(
692            entry_list
693                .entries()
694                .iter()
695                .cloned()
696                .map(AlternateIdIndexEntry::into_proto)
697                .collect::<Result<Vec<protos::pike_state::AlternateIdIndexEntry>, ProtoConversionError>>()?,
698        ));
699
700        Ok(entry_list_proto)
701    }
702}
703
704impl FromBytes<AlternateIdIndexEntryList> for AlternateIdIndexEntryList {
705    fn from_bytes(bytes: &[u8]) -> Result<AlternateIdIndexEntryList, ProtoConversionError> {
706        let proto: protos::pike_state::AlternateIdIndexEntryList = Message::parse_from_bytes(bytes)
707            .map_err(|_| {
708                ProtoConversionError::SerializationError(
709                    "Unable to get AlternateIdIndexEntryList from bytes".to_string(),
710                )
711            })?;
712
713        proto.into_native()
714    }
715}
716
717impl IntoBytes for AlternateIdIndexEntryList {
718    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
719        let proto = self.into_proto()?;
720        let bytes = proto.write_to_bytes().map_err(|_| {
721            ProtoConversionError::SerializationError(
722                "Unable to get bytes from AlternateIdIndexEntryList".to_string(),
723            )
724        })?;
725        Ok(bytes)
726    }
727}
728
729impl IntoProto<protos::pike_state::AlternateIdIndexEntryList> for AlternateIdIndexEntryList {}
730impl IntoNative<AlternateIdIndexEntryList> for protos::pike_state::AlternateIdIndexEntryList {}
731
732/// Returned if any required fields in an `AlternateIdIndexEntryList` are not present when being
733/// converted from the corresponding builder
734#[derive(Debug)]
735pub enum AlternateIdIndexEntryListBuildError {
736    MissingField(String),
737}
738
739impl StdError for AlternateIdIndexEntryListBuildError {
740    fn description(&self) -> &str {
741        match *self {
742            AlternateIdIndexEntryListBuildError::MissingField(ref msg) => msg,
743        }
744    }
745
746    fn cause(&self) -> Option<&dyn StdError> {
747        match *self {
748            AlternateIdIndexEntryListBuildError::MissingField(_) => None,
749        }
750    }
751}
752
753impl std::fmt::Display for AlternateIdIndexEntryListBuildError {
754    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
755        match *self {
756            AlternateIdIndexEntryListBuildError::MissingField(ref s) => {
757                write!(f, "MissingField: {}", s)
758            }
759        }
760    }
761}
762
763/// Builder used to create an `AlternateIdIndexEntryList`
764#[derive(Default, Clone)]
765pub struct AlternateIdIndexEntryListBuilder {
766    pub entries: Vec<AlternateIdIndexEntry>,
767}
768
769impl AlternateIdIndexEntryListBuilder {
770    pub fn new() -> Self {
771        AlternateIdIndexEntryListBuilder::default()
772    }
773
774    pub fn with_entries(
775        mut self,
776        entries: Vec<AlternateIdIndexEntry>,
777    ) -> AlternateIdIndexEntryListBuilder {
778        self.entries = entries;
779        self
780    }
781
782    pub fn build(self) -> Result<AlternateIdIndexEntryList, AlternateIdIndexEntryListBuildError> {
783        let entries = {
784            if self.entries.is_empty() {
785                return Err(AlternateIdIndexEntryListBuildError::MissingField(
786                    "'entries' cannot be empty".to_string(),
787                ));
788            } else {
789                self.entries
790            }
791        };
792
793        Ok(AlternateIdIndexEntryList { entries })
794    }
795}
796
797/// Native representation of the state object `AlternateId`
798///
799/// An `AlternateId` is a separate identifier from the `Organization`'s unique identifier, `org_id`.
800/// This enables certain smart contracts to identify an `Organization` within its own context.
801#[derive(Debug, Clone, PartialEq)]
802pub struct AlternateId {
803    id_type: String,
804    id: String,
805}
806
807impl AlternateId {
808    pub fn id_type(&self) -> &str {
809        &self.id_type
810    }
811
812    pub fn id(&self) -> &str {
813        &self.id
814    }
815}
816
817impl FromProto<protos::pike_state::AlternateId> for AlternateId {
818    fn from_proto(id: protos::pike_state::AlternateId) -> Result<Self, ProtoConversionError> {
819        Ok(AlternateId {
820            id_type: id.get_id_type().to_string(),
821            id: id.get_id().to_string(),
822        })
823    }
824}
825
826impl FromNative<AlternateId> for protos::pike_state::AlternateId {
827    fn from_native(id: AlternateId) -> Result<Self, ProtoConversionError> {
828        let mut alt_id_proto = protos::pike_state::AlternateId::new();
829
830        alt_id_proto.set_id_type(id.id_type().to_string());
831        alt_id_proto.set_id(id.id().to_string());
832
833        Ok(alt_id_proto)
834    }
835}
836
837impl FromBytes<AlternateId> for AlternateId {
838    fn from_bytes(bytes: &[u8]) -> Result<AlternateId, ProtoConversionError> {
839        let proto: protos::pike_state::AlternateId =
840            Message::parse_from_bytes(bytes).map_err(|_| {
841                ProtoConversionError::SerializationError(
842                    "Unable to get AlternateId from bytes".to_string(),
843                )
844            })?;
845        proto.into_native()
846    }
847}
848
849impl IntoBytes for AlternateId {
850    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
851        let proto = self.into_proto()?;
852        let bytes = proto.write_to_bytes().map_err(|_| {
853            ProtoConversionError::SerializationError(
854                "Unable to get bytes from AlternateId".to_string(),
855            )
856        })?;
857        Ok(bytes)
858    }
859}
860
861impl IntoProto<protos::pike_state::AlternateId> for AlternateId {}
862impl IntoNative<AlternateId> for protos::pike_state::AlternateId {}
863
864/// Returned if any required fields in an `AlternateId` are not present when being
865/// converted from the corresponding builder
866#[derive(Debug)]
867pub enum AlternateIdBuildError {
868    MissingField(String),
869}
870
871impl StdError for AlternateIdBuildError {
872    fn description(&self) -> &str {
873        match *self {
874            AlternateIdBuildError::MissingField(ref msg) => msg,
875        }
876    }
877
878    fn cause(&self) -> Option<&dyn StdError> {
879        match *self {
880            AlternateIdBuildError::MissingField(_) => None,
881        }
882    }
883}
884
885impl std::fmt::Display for AlternateIdBuildError {
886    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
887        match *self {
888            AlternateIdBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
889        }
890    }
891}
892
893/// Builder used to create an `AlternateId`
894#[derive(Default, Clone)]
895pub struct AlternateIdBuilder {
896    pub id_type: Option<String>,
897    pub id: Option<String>,
898}
899
900impl AlternateIdBuilder {
901    pub fn new() -> Self {
902        AlternateIdBuilder::default()
903    }
904
905    pub fn with_id_type(mut self, id_type: String) -> AlternateIdBuilder {
906        self.id_type = Some(id_type);
907        self
908    }
909
910    pub fn with_id(mut self, id: String) -> AlternateIdBuilder {
911        self.id = Some(id);
912        self
913    }
914
915    pub fn build(self) -> Result<AlternateId, AlternateIdBuildError> {
916        let id_type = self.id_type.ok_or_else(|| {
917            AlternateIdBuildError::MissingField("'id_type' field is required".to_string())
918        })?;
919
920        let id = self.id.ok_or_else(|| {
921            AlternateIdBuildError::MissingField("'id' field is required".to_string())
922        })?;
923
924        Ok(AlternateId { id_type, id })
925    }
926}
927
928/// Native representation of the state object `Agent`
929///
930/// An `Agent` is essentially a cryptographic public key which has a relationship, defined by the
931/// agent's `Role`s, with an `Organization`.
932#[derive(Debug, Clone, PartialEq)]
933pub struct Agent {
934    org_id: String,
935    public_key: String,
936    active: bool,
937    roles: Vec<String>,
938    metadata: Vec<KeyValueEntry>,
939}
940
941impl Agent {
942    pub fn org_id(&self) -> &str {
943        &self.org_id
944    }
945
946    pub fn public_key(&self) -> &str {
947        &self.public_key
948    }
949
950    pub fn active(&self) -> &bool {
951        &self.active
952    }
953
954    pub fn roles(&self) -> &[String] {
955        &self.roles
956    }
957
958    pub fn metadata(&self) -> &[KeyValueEntry] {
959        &self.metadata
960    }
961}
962
963impl FromProto<protos::pike_state::Agent> for Agent {
964    fn from_proto(agent: protos::pike_state::Agent) -> Result<Self, ProtoConversionError> {
965        Ok(Agent {
966            org_id: agent.get_org_id().to_string(),
967            public_key: agent.get_public_key().to_string(),
968            active: agent.get_active(),
969            roles: agent.get_roles().to_vec(),
970            metadata: agent
971                .get_metadata()
972                .iter()
973                .cloned()
974                .map(KeyValueEntry::from_proto)
975                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
976        })
977    }
978}
979
980impl FromNative<Agent> for protos::pike_state::Agent {
981    fn from_native(agent: Agent) -> Result<Self, ProtoConversionError> {
982        let mut agent_proto = protos::pike_state::Agent::new();
983
984        agent_proto.set_org_id(agent.org_id().to_string());
985        agent_proto.set_public_key(agent.public_key().to_string());
986        agent_proto.set_active(*agent.active());
987        agent_proto.set_org_id(agent.org_id().to_string());
988        agent_proto.set_roles(RepeatedField::from_vec(agent.roles().to_vec()));
989        agent_proto.set_metadata(RepeatedField::from_vec(
990            agent
991                .metadata()
992                .iter()
993                .cloned()
994                .map(KeyValueEntry::into_proto)
995                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
996                )?,
997        ));
998
999        Ok(agent_proto)
1000    }
1001}
1002
1003impl FromBytes<Agent> for Agent {
1004    fn from_bytes(bytes: &[u8]) -> Result<Agent, ProtoConversionError> {
1005        let proto: protos::pike_state::Agent = Message::parse_from_bytes(bytes).map_err(|_| {
1006            ProtoConversionError::SerializationError("Unable to get Agent from bytes".to_string())
1007        })?;
1008        proto.into_native()
1009    }
1010}
1011
1012impl IntoBytes for Agent {
1013    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1014        let proto = self.into_proto()?;
1015        let bytes = proto.write_to_bytes().map_err(|_| {
1016            ProtoConversionError::SerializationError("Unable to get bytes from Agent".to_string())
1017        })?;
1018        Ok(bytes)
1019    }
1020}
1021
1022impl IntoProto<protos::pike_state::Agent> for Agent {}
1023impl IntoNative<Agent> for protos::pike_state::Agent {}
1024
1025/// Returned if any required fields in an `Agent` are not present when being
1026/// converted from the corresponding builder
1027#[derive(Debug)]
1028pub enum AgentBuildError {
1029    MissingField(String),
1030}
1031
1032impl StdError for AgentBuildError {
1033    fn description(&self) -> &str {
1034        match *self {
1035            AgentBuildError::MissingField(ref msg) => msg,
1036        }
1037    }
1038
1039    fn cause(&self) -> Option<&dyn StdError> {
1040        match *self {
1041            AgentBuildError::MissingField(_) => None,
1042        }
1043    }
1044}
1045
1046impl std::fmt::Display for AgentBuildError {
1047    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1048        match *self {
1049            AgentBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1050        }
1051    }
1052}
1053
1054/// Builder used to create an `Agent`
1055#[derive(Default, Clone)]
1056pub struct AgentBuilder {
1057    pub org_id: Option<String>,
1058    pub public_key: Option<String>,
1059    pub active: Option<bool>,
1060    pub roles: Vec<String>,
1061    pub metadata: Vec<KeyValueEntry>,
1062}
1063
1064impl AgentBuilder {
1065    pub fn new() -> Self {
1066        AgentBuilder::default()
1067    }
1068
1069    pub fn with_org_id(mut self, org_id: String) -> AgentBuilder {
1070        self.org_id = Some(org_id);
1071        self
1072    }
1073
1074    pub fn with_public_key(mut self, public_key: String) -> AgentBuilder {
1075        self.public_key = Some(public_key);
1076        self
1077    }
1078
1079    pub fn with_active(mut self, active: bool) -> AgentBuilder {
1080        self.active = Some(active);
1081        self
1082    }
1083
1084    pub fn with_roles(mut self, roles: Vec<String>) -> AgentBuilder {
1085        self.roles = roles;
1086        self
1087    }
1088
1089    pub fn with_metadata(mut self, metadata: Vec<KeyValueEntry>) -> AgentBuilder {
1090        self.metadata = metadata;
1091        self
1092    }
1093
1094    pub fn build(self) -> Result<Agent, AgentBuildError> {
1095        let org_id = self.org_id.ok_or_else(|| {
1096            AgentBuildError::MissingField("'org_id' field is required".to_string())
1097        })?;
1098
1099        let public_key = self.public_key.ok_or_else(|| {
1100            AgentBuildError::MissingField("'public_key' field is required".to_string())
1101        })?;
1102
1103        let active = self.active.unwrap_or_default();
1104        let roles = self.roles;
1105        let metadata = self.metadata;
1106
1107        Ok(Agent {
1108            org_id,
1109            public_key,
1110            active,
1111            roles,
1112            metadata,
1113        })
1114    }
1115}
1116
1117/// Native representation of a list of `Agent`s
1118#[derive(Debug, Clone, PartialEq)]
1119pub struct AgentList {
1120    agents: Vec<Agent>,
1121}
1122
1123impl AgentList {
1124    pub fn agents(&self) -> &[Agent] {
1125        &self.agents
1126    }
1127}
1128
1129impl FromProto<protos::pike_state::AgentList> for AgentList {
1130    fn from_proto(agent_list: protos::pike_state::AgentList) -> Result<Self, ProtoConversionError> {
1131        Ok(AgentList {
1132            agents: agent_list
1133                .get_agents()
1134                .iter()
1135                .cloned()
1136                .map(Agent::from_proto)
1137                .collect::<Result<Vec<Agent>, ProtoConversionError>>()?,
1138        })
1139    }
1140}
1141
1142impl FromNative<AgentList> for protos::pike_state::AgentList {
1143    fn from_native(agent_list: AgentList) -> Result<Self, ProtoConversionError> {
1144        let mut agent_list_proto = protos::pike_state::AgentList::new();
1145
1146        agent_list_proto.set_agents(RepeatedField::from_vec(
1147            agent_list
1148                .agents()
1149                .iter()
1150                .cloned()
1151                .map(Agent::into_proto)
1152                .collect::<Result<Vec<protos::pike_state::Agent>, ProtoConversionError>>()?,
1153        ));
1154
1155        Ok(agent_list_proto)
1156    }
1157}
1158
1159impl FromBytes<AgentList> for AgentList {
1160    fn from_bytes(bytes: &[u8]) -> Result<AgentList, ProtoConversionError> {
1161        let proto: protos::pike_state::AgentList =
1162            Message::parse_from_bytes(bytes).map_err(|_| {
1163                ProtoConversionError::SerializationError(
1164                    "Unable to get AgentList from bytes".to_string(),
1165                )
1166            })?;
1167        proto.into_native()
1168    }
1169}
1170
1171impl IntoBytes for AgentList {
1172    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1173        let proto = self.into_proto()?;
1174        let bytes = proto.write_to_bytes().map_err(|_| {
1175            ProtoConversionError::SerializationError(
1176                "Unable to get bytes from AgentList".to_string(),
1177            )
1178        })?;
1179        Ok(bytes)
1180    }
1181}
1182
1183impl IntoProto<protos::pike_state::AgentList> for AgentList {}
1184impl IntoNative<AgentList> for protos::pike_state::AgentList {}
1185
1186/// Returned if any required fields in an `AgentList` are not present when being
1187/// converted from the corresponding builder
1188#[derive(Debug)]
1189pub enum AgentListBuildError {
1190    MissingField(String),
1191}
1192
1193impl StdError for AgentListBuildError {
1194    fn description(&self) -> &str {
1195        match *self {
1196            AgentListBuildError::MissingField(ref msg) => msg,
1197        }
1198    }
1199
1200    fn cause(&self) -> Option<&dyn StdError> {
1201        match *self {
1202            AgentListBuildError::MissingField(_) => None,
1203        }
1204    }
1205}
1206
1207impl std::fmt::Display for AgentListBuildError {
1208    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1209        match *self {
1210            AgentListBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1211        }
1212    }
1213}
1214
1215/// Builder used to create an `AgentList`
1216#[derive(Default, Clone)]
1217pub struct AgentListBuilder {
1218    pub agents: Vec<Agent>,
1219}
1220
1221impl AgentListBuilder {
1222    pub fn new() -> Self {
1223        AgentListBuilder::default()
1224    }
1225
1226    pub fn with_agents(mut self, agents: Vec<Agent>) -> AgentListBuilder {
1227        self.agents = agents;
1228        self
1229    }
1230
1231    pub fn build(self) -> Result<AgentList, AgentListBuildError> {
1232        let agents = {
1233            if self.agents.is_empty() {
1234                return Err(AgentListBuildError::MissingField(
1235                    "'agents' cannot be empty".to_string(),
1236                ));
1237            } else {
1238                self.agents
1239            }
1240        };
1241
1242        Ok(AgentList { agents })
1243    }
1244}
1245
1246/// Native representation of the state object `Organization`
1247///
1248/// `Organization`s provide a top-level identity to associate the lower-level objects to across
1249/// smart contracts.
1250#[derive(Debug, Clone, PartialEq)]
1251pub struct Organization {
1252    org_id: String,
1253    name: String,
1254    locations: Vec<String>,
1255    alternate_ids: Vec<AlternateId>,
1256    metadata: Vec<KeyValueEntry>,
1257}
1258
1259impl Organization {
1260    pub fn org_id(&self) -> &str {
1261        &self.org_id
1262    }
1263
1264    pub fn name(&self) -> &str {
1265        &self.name
1266    }
1267
1268    pub fn locations(&self) -> &[String] {
1269        &self.locations
1270    }
1271
1272    pub fn alternate_ids(&self) -> &[AlternateId] {
1273        &self.alternate_ids
1274    }
1275
1276    pub fn metadata(&self) -> &[KeyValueEntry] {
1277        &self.metadata
1278    }
1279}
1280
1281impl FromProto<protos::pike_state::Organization> for Organization {
1282    fn from_proto(org: protos::pike_state::Organization) -> Result<Self, ProtoConversionError> {
1283        Ok(Organization {
1284            org_id: org.get_org_id().to_string(),
1285            name: org.get_name().to_string(),
1286            locations: org.get_locations().to_vec(),
1287            alternate_ids: org
1288                .get_alternate_ids()
1289                .iter()
1290                .cloned()
1291                .map(AlternateId::from_proto)
1292                .collect::<Result<Vec<AlternateId>, ProtoConversionError>>()?,
1293            metadata: org
1294                .get_metadata()
1295                .iter()
1296                .cloned()
1297                .map(KeyValueEntry::from_proto)
1298                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
1299        })
1300    }
1301}
1302
1303impl FromNative<Organization> for protos::pike_state::Organization {
1304    fn from_native(org: Organization) -> Result<Self, ProtoConversionError> {
1305        let mut org_proto = protos::pike_state::Organization::new();
1306
1307        org_proto.set_org_id(org.org_id().to_string());
1308        org_proto.set_name(org.name().to_string());
1309        org_proto.set_locations(RepeatedField::from_vec(org.locations().to_vec()));
1310        org_proto.set_alternate_ids(RepeatedField::from_vec(
1311            org.alternate_ids()
1312                .iter()
1313                .cloned()
1314                .map(AlternateId::into_proto)
1315                .collect::<Result<Vec<protos::pike_state::AlternateId>, ProtoConversionError>>()?,
1316        ));
1317        org_proto.set_metadata(RepeatedField::from_vec(
1318            org.metadata()
1319                .iter()
1320                .cloned()
1321                .map(KeyValueEntry::into_proto)
1322                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
1323                )?,
1324        ));
1325
1326        Ok(org_proto)
1327    }
1328}
1329
1330impl FromBytes<Organization> for Organization {
1331    fn from_bytes(bytes: &[u8]) -> Result<Organization, ProtoConversionError> {
1332        let proto: protos::pike_state::Organization =
1333            Message::parse_from_bytes(bytes).map_err(|_| {
1334                ProtoConversionError::SerializationError(
1335                    "Unable to get Organization from bytes".to_string(),
1336                )
1337            })?;
1338        proto.into_native()
1339    }
1340}
1341
1342impl IntoBytes for Organization {
1343    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1344        let proto = self.into_proto()?;
1345        let bytes = proto.write_to_bytes().map_err(|_| {
1346            ProtoConversionError::SerializationError(
1347                "Unable to get bytes from Organization".to_string(),
1348            )
1349        })?;
1350        Ok(bytes)
1351    }
1352}
1353
1354impl IntoProto<protos::pike_state::Organization> for Organization {}
1355impl IntoNative<Organization> for protos::pike_state::Organization {}
1356
1357/// Returned if any required fields in an `Organization` are not present when being
1358/// converted from the corresponding builder
1359#[derive(Debug)]
1360pub enum OrganizationBuildError {
1361    MissingField(String),
1362}
1363
1364impl StdError for OrganizationBuildError {
1365    fn description(&self) -> &str {
1366        match *self {
1367            OrganizationBuildError::MissingField(ref msg) => msg,
1368        }
1369    }
1370
1371    fn cause(&self) -> Option<&dyn StdError> {
1372        match *self {
1373            OrganizationBuildError::MissingField(_) => None,
1374        }
1375    }
1376}
1377
1378impl std::fmt::Display for OrganizationBuildError {
1379    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1380        match *self {
1381            OrganizationBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1382        }
1383    }
1384}
1385
1386/// Builder used to create an `Organization`
1387#[derive(Default, Clone)]
1388pub struct OrganizationBuilder {
1389    pub org_id: Option<String>,
1390    pub name: Option<String>,
1391    pub locations: Vec<String>,
1392    pub alternate_ids: Vec<AlternateId>,
1393    pub metadata: Vec<KeyValueEntry>,
1394}
1395
1396impl OrganizationBuilder {
1397    pub fn new() -> Self {
1398        OrganizationBuilder::default()
1399    }
1400
1401    pub fn with_org_id(mut self, org_id: String) -> OrganizationBuilder {
1402        self.org_id = Some(org_id);
1403        self
1404    }
1405
1406    pub fn with_name(mut self, name: String) -> OrganizationBuilder {
1407        self.name = Some(name);
1408        self
1409    }
1410
1411    pub fn with_locations(mut self, locations: Vec<String>) -> OrganizationBuilder {
1412        self.locations = locations;
1413        self
1414    }
1415
1416    pub fn with_alternate_ids(mut self, alternate_ids: Vec<AlternateId>) -> OrganizationBuilder {
1417        self.alternate_ids = alternate_ids;
1418        self
1419    }
1420
1421    pub fn with_metadata(mut self, metadata: Vec<KeyValueEntry>) -> OrganizationBuilder {
1422        self.metadata = metadata;
1423        self
1424    }
1425
1426    pub fn build(self) -> Result<Organization, OrganizationBuildError> {
1427        let org_id = self.org_id.ok_or_else(|| {
1428            OrganizationBuildError::MissingField("'org_id' field is required".to_string())
1429        })?;
1430
1431        let name = self.name.ok_or_else(|| {
1432            OrganizationBuildError::MissingField("'name' field is required".to_string())
1433        })?;
1434
1435        let locations = self.locations;
1436
1437        let alternate_ids = self.alternate_ids;
1438
1439        let metadata = self.metadata;
1440
1441        Ok(Organization {
1442            org_id,
1443            name,
1444            locations,
1445            alternate_ids,
1446            metadata,
1447        })
1448    }
1449}
1450
1451/// Native representation of a list of `Organization`s
1452#[derive(Debug, Clone, PartialEq)]
1453pub struct OrganizationList {
1454    organizations: Vec<Organization>,
1455}
1456
1457impl OrganizationList {
1458    pub fn organizations(&self) -> &[Organization] {
1459        &self.organizations
1460    }
1461}
1462
1463impl FromProto<protos::pike_state::OrganizationList> for OrganizationList {
1464    fn from_proto(
1465        organization_list: protos::pike_state::OrganizationList,
1466    ) -> Result<Self, ProtoConversionError> {
1467        Ok(OrganizationList {
1468            organizations: organization_list
1469                .get_organizations()
1470                .iter()
1471                .cloned()
1472                .map(Organization::from_proto)
1473                .collect::<Result<Vec<Organization>, ProtoConversionError>>()?,
1474        })
1475    }
1476}
1477
1478impl FromNative<OrganizationList> for protos::pike_state::OrganizationList {
1479    fn from_native(org_list: OrganizationList) -> Result<Self, ProtoConversionError> {
1480        let mut org_list_proto = protos::pike_state::OrganizationList::new();
1481
1482        org_list_proto.set_organizations(RepeatedField::from_vec(
1483            org_list
1484                .organizations()
1485                .iter()
1486                .cloned()
1487                .map(Organization::into_proto)
1488                .collect::<Result<Vec<protos::pike_state::Organization>, ProtoConversionError>>()?,
1489        ));
1490
1491        Ok(org_list_proto)
1492    }
1493}
1494
1495impl FromBytes<OrganizationList> for OrganizationList {
1496    fn from_bytes(bytes: &[u8]) -> Result<OrganizationList, ProtoConversionError> {
1497        let proto: protos::pike_state::OrganizationList = Message::parse_from_bytes(bytes)
1498            .map_err(|_| {
1499                ProtoConversionError::SerializationError(
1500                    "Unable to get OrganizationList from bytes".to_string(),
1501                )
1502            })?;
1503        proto.into_native()
1504    }
1505}
1506
1507impl IntoBytes for OrganizationList {
1508    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1509        let proto = self.into_proto()?;
1510        let bytes = proto.write_to_bytes().map_err(|_| {
1511            ProtoConversionError::SerializationError(
1512                "Unable to get bytes from OrganizationList".to_string(),
1513            )
1514        })?;
1515        Ok(bytes)
1516    }
1517}
1518
1519impl IntoProto<protos::pike_state::OrganizationList> for OrganizationList {}
1520impl IntoNative<OrganizationList> for protos::pike_state::OrganizationList {}
1521
1522/// Returned if any required fields in an `OrganizationList` are not present when being
1523/// converted from the corresponding builder
1524#[derive(Debug)]
1525pub enum OrganizationListBuildError {
1526    MissingField(String),
1527}
1528
1529impl StdError for OrganizationListBuildError {
1530    fn description(&self) -> &str {
1531        match *self {
1532            OrganizationListBuildError::MissingField(ref msg) => msg,
1533        }
1534    }
1535
1536    fn cause(&self) -> Option<&dyn StdError> {
1537        match *self {
1538            OrganizationListBuildError::MissingField(_) => None,
1539        }
1540    }
1541}
1542
1543impl std::fmt::Display for OrganizationListBuildError {
1544    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1545        match *self {
1546            OrganizationListBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1547        }
1548    }
1549}
1550
1551/// Builder used to create an `OrganizationList`
1552#[derive(Default, Clone)]
1553pub struct OrganizationListBuilder {
1554    pub organizations: Vec<Organization>,
1555}
1556
1557impl OrganizationListBuilder {
1558    pub fn new() -> Self {
1559        OrganizationListBuilder::default()
1560    }
1561
1562    pub fn with_organizations(
1563        mut self,
1564        organizations: Vec<Organization>,
1565    ) -> OrganizationListBuilder {
1566        self.organizations = organizations;
1567        self
1568    }
1569
1570    pub fn build(self) -> Result<OrganizationList, OrganizationListBuildError> {
1571        let organizations = {
1572            if self.organizations.is_empty() {
1573                return Err(OrganizationListBuildError::MissingField(
1574                    "'organization' cannot be empty".to_string(),
1575                ));
1576            } else {
1577                self.organizations
1578            }
1579        };
1580
1581        Ok(OrganizationList { organizations })
1582    }
1583}
1584
1585#[cfg(test)]
1586mod tests {
1587    use super::*;
1588
1589    #[test]
1590    /// Validate that a `KeyValueEntry` is built correctly
1591    fn check_key_value_entry_builder() {
1592        let builder = KeyValueEntryBuilder::new();
1593        let key_value = builder
1594            .with_key("Key".to_string())
1595            .with_value("Value".to_string())
1596            .build()
1597            .unwrap();
1598
1599        assert_eq!(key_value.key(), "Key");
1600        assert_eq!(key_value.value(), "Value");
1601    }
1602
1603    #[test]
1604    /// Validate that a `KeyValueEntry` may be correctly converted into bytes and back to its
1605    /// native representation
1606    fn check_key_value_entry_bytes() {
1607        let builder = KeyValueEntryBuilder::new();
1608        let original = builder
1609            .with_key("Key".to_string())
1610            .with_value("Value".to_string())
1611            .build()
1612            .unwrap();
1613
1614        let bytes = original.clone().into_bytes().unwrap();
1615        let key_value = KeyValueEntry::from_bytes(&bytes).unwrap();
1616        assert_eq!(key_value, original);
1617    }
1618
1619    #[test]
1620    /// Validate that an `Agent` is built correctly
1621    fn check_agent_builder() {
1622        let builder = KeyValueEntryBuilder::new();
1623        let key_value = builder
1624            .with_key("Key".to_string())
1625            .with_value("Value".to_string())
1626            .build()
1627            .unwrap();
1628
1629        let builder = AgentBuilder::new();
1630        let agent = builder
1631            .with_org_id("organization".to_string())
1632            .with_public_key("public_key".to_string())
1633            .with_active(true)
1634            .with_roles(vec!["Role".to_string()])
1635            .with_metadata(vec![key_value.clone()])
1636            .build()
1637            .unwrap();
1638
1639        assert_eq!(agent.org_id(), "organization");
1640        assert_eq!(agent.public_key(), "public_key");
1641        assert!(agent.active());
1642        assert_eq!(agent.roles(), ["Role".to_string()]);
1643        assert_eq!(agent.metadata(), [key_value]);
1644    }
1645
1646    #[test]
1647    /// Validate that an `Agent` may be correctly converted into bytes and back to its native
1648    /// representation
1649    fn check_agent_bytes() {
1650        let builder = KeyValueEntryBuilder::new();
1651        let key_value = builder
1652            .with_key("Key".to_string())
1653            .with_value("Value".to_string())
1654            .build()
1655            .unwrap();
1656
1657        let builder = AgentBuilder::new();
1658        let original = builder
1659            .with_org_id("organization".to_string())
1660            .with_public_key("public_key".to_string())
1661            .with_active(true)
1662            .with_roles(vec!["Role".to_string()])
1663            .with_metadata(vec![key_value.clone()])
1664            .build()
1665            .unwrap();
1666
1667        let bytes = original.clone().into_bytes().unwrap();
1668        let agent = Agent::from_bytes(&bytes).unwrap();
1669        assert_eq!(agent, original);
1670    }
1671
1672    #[test]
1673    /// Validate that an `AgentList` is built correctly
1674    fn check_agent_list_builder() {
1675        let builder = KeyValueEntryBuilder::new();
1676        let key_value = builder
1677            .with_key("Key".to_string())
1678            .with_value("Value".to_string())
1679            .build()
1680            .unwrap();
1681
1682        let builder = AgentBuilder::new();
1683        let agent = builder
1684            .with_org_id("organization".to_string())
1685            .with_public_key("public_key".to_string())
1686            .with_active(true)
1687            .with_roles(vec!["Role".to_string()])
1688            .with_metadata(vec![key_value.clone()])
1689            .build()
1690            .unwrap();
1691
1692        let builder = AgentListBuilder::new();
1693        let agent_list = builder.with_agents(vec![agent.clone()]).build().unwrap();
1694
1695        assert_eq!(agent_list.agents(), [agent])
1696    }
1697
1698    #[test]
1699    /// Validate that an `AgentList` may be converted into bytes and back to its native
1700    /// representation
1701    fn check_agent_list_bytes() {
1702        let builder = KeyValueEntryBuilder::new();
1703        let key_value = builder
1704            .with_key("Key".to_string())
1705            .with_value("Value".to_string())
1706            .build()
1707            .unwrap();
1708
1709        let builder = AgentBuilder::new();
1710        let agent = builder
1711            .with_org_id("organization".to_string())
1712            .with_public_key("public_key".to_string())
1713            .with_active(true)
1714            .with_roles(vec!["Role".to_string()])
1715            .with_metadata(vec![key_value.clone()])
1716            .build()
1717            .unwrap();
1718
1719        let builder = AgentListBuilder::new();
1720        let original = builder.with_agents(vec![agent.clone()]).build().unwrap();
1721
1722        let bytes = original.clone().into_bytes().unwrap();
1723        let agent_list = AgentList::from_bytes(&bytes).unwrap();
1724        assert_eq!(agent_list, original);
1725    }
1726
1727    #[test]
1728    /// Validate that an `Organization` is built correctly
1729    fn check_organization_builder() {
1730        let builder = KeyValueEntryBuilder::new();
1731        let key_value = builder
1732            .with_key("Key".to_string())
1733            .with_value("Value".to_string())
1734            .build()
1735            .unwrap();
1736
1737        let builder = OrganizationBuilder::new();
1738        let organization = builder
1739            .with_org_id("organization".to_string())
1740            .with_name("name".to_string())
1741            .with_locations(vec!["location".to_string()])
1742            .with_metadata(vec![key_value.clone()])
1743            .build()
1744            .unwrap();
1745
1746        assert_eq!(organization.org_id(), "organization");
1747        assert_eq!(organization.name(), "name");
1748        assert_eq!(organization.locations(), ["location"]);
1749        assert_eq!(organization.metadata(), [key_value]);
1750    }
1751
1752    #[test]
1753    /// Validate that an `Organization` may be correctly converted into bytes and back to its
1754    /// native representation
1755    fn check_organization_bytes() {
1756        let builder = KeyValueEntryBuilder::new();
1757        let key_value = builder
1758            .with_key("Key".to_string())
1759            .with_value("Value".to_string())
1760            .build()
1761            .unwrap();
1762
1763        let builder = OrganizationBuilder::new();
1764        let original = builder
1765            .with_org_id("organization".to_string())
1766            .with_name("name".to_string())
1767            .with_locations(vec!["locations".to_string()])
1768            .with_metadata(vec![key_value.clone()])
1769            .build()
1770            .unwrap();
1771
1772        let bytes = original.clone().into_bytes().unwrap();
1773        let org = Organization::from_bytes(&bytes).unwrap();
1774        assert_eq!(org, original);
1775    }
1776
1777    #[test]
1778    /// Validate that an `OrganizationList` is built correctly
1779    fn check_organization_lists_builder() {
1780        let builder = KeyValueEntryBuilder::new();
1781        let key_value = builder
1782            .with_key("Key".to_string())
1783            .with_value("Value".to_string())
1784            .build()
1785            .unwrap();
1786
1787        let builder = OrganizationBuilder::new();
1788        let organization = builder
1789            .with_org_id("organization".to_string())
1790            .with_name("name".to_string())
1791            .with_locations(vec!["location".to_string()])
1792            .with_metadata(vec![key_value.clone()])
1793            .build()
1794            .unwrap();
1795
1796        let builder = OrganizationListBuilder::new();
1797        let organization_list = builder
1798            .with_organizations(vec![organization.clone()])
1799            .build()
1800            .unwrap();
1801
1802        assert_eq!(organization_list.organizations(), [organization])
1803    }
1804
1805    #[test]
1806    /// Validate that an `OrganizationList` may be correctly converted into bytes and back to its
1807    /// native representation
1808    fn check_organization_list_bytes() {
1809        let builder = KeyValueEntryBuilder::new();
1810        let key_value = builder
1811            .with_key("Key".to_string())
1812            .with_value("Value".to_string())
1813            .build()
1814            .unwrap();
1815
1816        let builder = OrganizationBuilder::new();
1817        let organization = builder
1818            .with_org_id("organization".to_string())
1819            .with_name("name".to_string())
1820            .with_locations(vec!["locations".to_string()])
1821            .with_metadata(vec![key_value.clone()])
1822            .build()
1823            .unwrap();
1824
1825        let builder = OrganizationListBuilder::new();
1826        let original = builder
1827            .with_organizations(vec![organization.clone()])
1828            .build()
1829            .unwrap();
1830
1831        let bytes = original.clone().into_bytes().unwrap();
1832        let org_list = OrganizationList::from_bytes(&bytes).unwrap();
1833        assert_eq!(org_list, original);
1834    }
1835}