grid_sdk/protocol/pike/
payload.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 transaction payloads
16
17use protobuf::Message;
18use protobuf::RepeatedField;
19
20use std::error::Error as StdError;
21
22use crate::protocol::pike::state::{AlternateId, KeyValueEntry};
23use crate::protos;
24use crate::protos::{
25    FromBytes, FromNative, FromProto, IntoBytes, IntoNative, IntoProto, ProtoConversionError,
26};
27
28/// The Pike payload's action envelope
29#[derive(Debug, Clone, PartialEq)]
30pub enum Action {
31    CreateAgent(CreateAgentAction),
32    UpdateAgent(UpdateAgentAction),
33    DeleteAgent(DeleteAgentAction),
34    CreateOrganization(CreateOrganizationAction),
35    UpdateOrganization(UpdateOrganizationAction),
36    DeleteOrganization(DeleteOrganizationAction),
37    CreateRole(CreateRoleAction),
38    UpdateRole(UpdateRoleAction),
39    DeleteRole(DeleteRoleAction),
40}
41
42/// Native representation of the "create agent" payload
43#[derive(Debug, Default, Clone, PartialEq)]
44pub struct CreateAgentAction {
45    org_id: String,
46    public_key: String,
47    active: bool,
48    roles: Vec<String>,
49    metadata: Vec<KeyValueEntry>,
50}
51
52impl CreateAgentAction {
53    pub fn org_id(&self) -> &str {
54        &self.org_id
55    }
56
57    pub fn public_key(&self) -> &str {
58        &self.public_key
59    }
60
61    pub fn active(&self) -> &bool {
62        &self.active
63    }
64
65    pub fn roles(&self) -> &[String] {
66        &self.roles
67    }
68
69    pub fn metadata(&self) -> &[KeyValueEntry] {
70        &self.metadata
71    }
72}
73
74impl FromProto<protos::pike_payload::CreateAgentAction> for CreateAgentAction {
75    fn from_proto(
76        create_agent: protos::pike_payload::CreateAgentAction,
77    ) -> Result<Self, ProtoConversionError> {
78        Ok(CreateAgentAction {
79            org_id: create_agent.get_org_id().to_string(),
80            public_key: create_agent.get_public_key().to_string(),
81            active: create_agent.get_active(),
82            roles: create_agent.get_roles().to_vec(),
83            metadata: create_agent
84                .get_metadata()
85                .iter()
86                .cloned()
87                .map(KeyValueEntry::from_proto)
88                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
89        })
90    }
91}
92
93impl FromNative<CreateAgentAction> for protos::pike_payload::CreateAgentAction {
94    fn from_native(create_agent: CreateAgentAction) -> Result<Self, ProtoConversionError> {
95        let mut proto_create_agent = protos::pike_payload::CreateAgentAction::new();
96
97        proto_create_agent.set_org_id(create_agent.org_id().to_string());
98        proto_create_agent.set_public_key(create_agent.public_key().to_string());
99        proto_create_agent.set_active(*create_agent.active());
100        proto_create_agent.set_org_id(create_agent.org_id().to_string());
101        proto_create_agent.set_roles(RepeatedField::from_vec(create_agent.roles().to_vec()));
102        proto_create_agent.set_metadata(RepeatedField::from_vec(
103            create_agent
104                .metadata()
105                .iter()
106                .cloned()
107                .map(KeyValueEntry::into_proto)
108                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
109                )?,
110        ));
111
112        Ok(proto_create_agent)
113    }
114}
115
116impl FromBytes<CreateAgentAction> for CreateAgentAction {
117    fn from_bytes(bytes: &[u8]) -> Result<CreateAgentAction, ProtoConversionError> {
118        let proto: protos::pike_payload::CreateAgentAction = Message::parse_from_bytes(bytes)
119            .map_err(|_| {
120                ProtoConversionError::SerializationError(
121                    "Unable to get CreateAgentAction from bytes".to_string(),
122                )
123            })?;
124        proto.into_native()
125    }
126}
127
128impl IntoBytes for CreateAgentAction {
129    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
130        let proto = self.into_proto()?;
131        let bytes = proto.write_to_bytes().map_err(|_| {
132            ProtoConversionError::SerializationError(
133                "Unable to get bytes from CreateAgentAction".to_string(),
134            )
135        })?;
136        Ok(bytes)
137    }
138}
139
140impl IntoProto<protos::pike_payload::CreateAgentAction> for CreateAgentAction {}
141impl IntoNative<CreateAgentAction> for protos::pike_payload::CreateAgentAction {}
142
143/// Returned if any required fields in a `CreateAgentAction` are not present when being
144/// converted from the corresponding builder
145#[derive(Debug)]
146pub enum CreateAgentActionBuildError {
147    MissingField(String),
148}
149
150impl StdError for CreateAgentActionBuildError {
151    fn description(&self) -> &str {
152        match *self {
153            CreateAgentActionBuildError::MissingField(ref msg) => msg,
154        }
155    }
156
157    fn cause(&self) -> Option<&dyn StdError> {
158        match *self {
159            CreateAgentActionBuildError::MissingField(_) => None,
160        }
161    }
162}
163
164impl std::fmt::Display for CreateAgentActionBuildError {
165    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
166        match *self {
167            CreateAgentActionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
168        }
169    }
170}
171
172/// Builder to create a "create agent" action
173#[derive(Default, Clone)]
174pub struct CreateAgentActionBuilder {
175    pub org_id: Option<String>,
176    pub public_key: Option<String>,
177    pub active: Option<bool>,
178    pub roles: Vec<String>,
179    pub metadata: Vec<KeyValueEntry>,
180}
181
182impl CreateAgentActionBuilder {
183    pub fn new() -> Self {
184        CreateAgentActionBuilder::default()
185    }
186
187    pub fn with_org_id(mut self, org_id: String) -> CreateAgentActionBuilder {
188        self.org_id = Some(org_id);
189        self
190    }
191
192    pub fn with_public_key(mut self, public_key: String) -> CreateAgentActionBuilder {
193        self.public_key = Some(public_key);
194        self
195    }
196
197    pub fn with_active(mut self, active: bool) -> CreateAgentActionBuilder {
198        self.active = Some(active);
199        self
200    }
201
202    pub fn with_roles(mut self, roles: Vec<String>) -> CreateAgentActionBuilder {
203        self.roles = roles;
204        self
205    }
206
207    pub fn with_metadata(mut self, metadata: Vec<KeyValueEntry>) -> CreateAgentActionBuilder {
208        self.metadata = metadata;
209        self
210    }
211
212    pub fn build(self) -> Result<CreateAgentAction, CreateAgentActionBuildError> {
213        let org_id = self.org_id.ok_or_else(|| {
214            CreateAgentActionBuildError::MissingField("'org_id' field is required".to_string())
215        })?;
216
217        let public_key = self.public_key.ok_or_else(|| {
218            CreateAgentActionBuildError::MissingField("'public_key' field is required".to_string())
219        })?;
220
221        let active = self.active.unwrap_or_default();
222        let roles = self.roles;
223        let metadata = self.metadata;
224
225        Ok(CreateAgentAction {
226            org_id,
227            public_key,
228            active,
229            roles,
230            metadata,
231        })
232    }
233}
234
235/// Native representation of the "update agent" action payload
236#[derive(Debug, Default, Clone, PartialEq)]
237pub struct UpdateAgentAction {
238    org_id: String,
239    public_key: String,
240    active: bool,
241    roles: Vec<String>,
242    metadata: Vec<KeyValueEntry>,
243}
244
245impl UpdateAgentAction {
246    pub fn org_id(&self) -> &str {
247        &self.org_id
248    }
249
250    pub fn public_key(&self) -> &str {
251        &self.public_key
252    }
253
254    pub fn active(&self) -> &bool {
255        &self.active
256    }
257
258    pub fn roles(&self) -> &[String] {
259        &self.roles
260    }
261
262    pub fn metadata(&self) -> &[KeyValueEntry] {
263        &self.metadata
264    }
265}
266
267impl FromProto<protos::pike_payload::UpdateAgentAction> for UpdateAgentAction {
268    fn from_proto(
269        update_agent: protos::pike_payload::UpdateAgentAction,
270    ) -> Result<Self, ProtoConversionError> {
271        Ok(UpdateAgentAction {
272            org_id: update_agent.get_org_id().to_string(),
273            public_key: update_agent.get_public_key().to_string(),
274            active: update_agent.get_active(),
275            roles: update_agent.get_roles().to_vec(),
276            metadata: update_agent
277                .get_metadata()
278                .iter()
279                .cloned()
280                .map(KeyValueEntry::from_proto)
281                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
282        })
283    }
284}
285
286impl FromNative<UpdateAgentAction> for protos::pike_payload::UpdateAgentAction {
287    fn from_native(update_agent: UpdateAgentAction) -> Result<Self, ProtoConversionError> {
288        let mut proto_update_agent = protos::pike_payload::UpdateAgentAction::new();
289
290        proto_update_agent.set_org_id(update_agent.org_id().to_string());
291        proto_update_agent.set_public_key(update_agent.public_key().to_string());
292        proto_update_agent.set_active(*update_agent.active());
293        proto_update_agent.set_org_id(update_agent.org_id().to_string());
294        proto_update_agent.set_roles(RepeatedField::from_vec(update_agent.roles().to_vec()));
295        proto_update_agent.set_metadata(RepeatedField::from_vec(
296            update_agent
297                .metadata()
298                .iter()
299                .cloned()
300                .map(KeyValueEntry::into_proto)
301                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
302                )?,
303        ));
304
305        Ok(proto_update_agent)
306    }
307}
308
309impl FromBytes<UpdateAgentAction> for UpdateAgentAction {
310    fn from_bytes(bytes: &[u8]) -> Result<UpdateAgentAction, ProtoConversionError> {
311        let proto: protos::pike_payload::UpdateAgentAction = Message::parse_from_bytes(bytes)
312            .map_err(|_| {
313                ProtoConversionError::SerializationError(
314                    "Unable to get UpdateAgentAction from bytes".to_string(),
315                )
316            })?;
317        proto.into_native()
318    }
319}
320
321impl IntoBytes for UpdateAgentAction {
322    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
323        let proto = self.into_proto()?;
324        let bytes = proto.write_to_bytes().map_err(|_| {
325            ProtoConversionError::SerializationError(
326                "Unable to get bytes from UpdateAgentAction".to_string(),
327            )
328        })?;
329        Ok(bytes)
330    }
331}
332
333impl IntoProto<protos::pike_payload::UpdateAgentAction> for UpdateAgentAction {}
334impl IntoNative<UpdateAgentAction> for protos::pike_payload::UpdateAgentAction {}
335
336/// Returned if any required fields in an `UpdateAgentAction` are not present when being
337/// converted from the corresponding builder
338#[derive(Debug)]
339pub enum UpdateAgentActionBuildError {
340    MissingField(String),
341}
342
343impl StdError for UpdateAgentActionBuildError {
344    fn description(&self) -> &str {
345        match *self {
346            UpdateAgentActionBuildError::MissingField(ref msg) => msg,
347        }
348    }
349
350    fn cause(&self) -> Option<&dyn StdError> {
351        match *self {
352            UpdateAgentActionBuildError::MissingField(_) => None,
353        }
354    }
355}
356
357impl std::fmt::Display for UpdateAgentActionBuildError {
358    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
359        match *self {
360            UpdateAgentActionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
361        }
362    }
363}
364
365/// Builder used to create an "update agent" action
366#[derive(Default, Clone)]
367pub struct UpdateAgentActionBuilder {
368    pub org_id: Option<String>,
369    pub public_key: Option<String>,
370    pub active: Option<bool>,
371    pub roles: Vec<String>,
372    pub metadata: Vec<KeyValueEntry>,
373}
374
375impl UpdateAgentActionBuilder {
376    pub fn new() -> Self {
377        UpdateAgentActionBuilder::default()
378    }
379
380    pub fn with_org_id(mut self, org_id: String) -> UpdateAgentActionBuilder {
381        self.org_id = Some(org_id);
382        self
383    }
384
385    pub fn with_public_key(mut self, public_key: String) -> UpdateAgentActionBuilder {
386        self.public_key = Some(public_key);
387        self
388    }
389
390    pub fn with_active(mut self, active: bool) -> UpdateAgentActionBuilder {
391        self.active = Some(active);
392        self
393    }
394
395    pub fn with_roles(mut self, roles: Vec<String>) -> UpdateAgentActionBuilder {
396        self.roles = roles;
397        self
398    }
399
400    pub fn with_metadata(mut self, metadata: Vec<KeyValueEntry>) -> UpdateAgentActionBuilder {
401        self.metadata = metadata;
402        self
403    }
404
405    pub fn build(self) -> Result<UpdateAgentAction, UpdateAgentActionBuildError> {
406        let org_id = self.org_id.ok_or_else(|| {
407            UpdateAgentActionBuildError::MissingField("'org_id' field is required".to_string())
408        })?;
409
410        let public_key = self.public_key.ok_or_else(|| {
411            UpdateAgentActionBuildError::MissingField("'public_key' field is required".to_string())
412        })?;
413
414        let active = self.active.unwrap_or_default();
415        let roles = self.roles;
416        let metadata = self.metadata;
417
418        Ok(UpdateAgentAction {
419            org_id,
420            public_key,
421            active,
422            roles,
423            metadata,
424        })
425    }
426}
427
428/// Native representation of the "delete agent" action payload
429#[derive(Debug, Default, Clone, PartialEq)]
430pub struct DeleteAgentAction {
431    org_id: String,
432    public_key: String,
433}
434
435impl DeleteAgentAction {
436    pub fn org_id(&self) -> &str {
437        &self.org_id
438    }
439
440    pub fn public_key(&self) -> &str {
441        &self.public_key
442    }
443}
444
445impl FromProto<protos::pike_payload::DeleteAgentAction> for DeleteAgentAction {
446    fn from_proto(
447        delete_agent: protos::pike_payload::DeleteAgentAction,
448    ) -> Result<Self, ProtoConversionError> {
449        Ok(DeleteAgentAction {
450            org_id: delete_agent.get_org_id().to_string(),
451            public_key: delete_agent.get_public_key().to_string(),
452        })
453    }
454}
455
456impl FromNative<DeleteAgentAction> for protos::pike_payload::DeleteAgentAction {
457    fn from_native(delete_agent: DeleteAgentAction) -> Result<Self, ProtoConversionError> {
458        let mut proto_delete_agent = protos::pike_payload::DeleteAgentAction::new();
459
460        proto_delete_agent.set_org_id(delete_agent.org_id().to_string());
461        proto_delete_agent.set_public_key(delete_agent.public_key().to_string());
462
463        Ok(proto_delete_agent)
464    }
465}
466
467impl FromBytes<DeleteAgentAction> for DeleteAgentAction {
468    fn from_bytes(bytes: &[u8]) -> Result<DeleteAgentAction, ProtoConversionError> {
469        let proto: protos::pike_payload::DeleteAgentAction = Message::parse_from_bytes(bytes)
470            .map_err(|_| {
471                ProtoConversionError::SerializationError(
472                    "Unable to get DeleteAgentAction from bytes".to_string(),
473                )
474            })?;
475        proto.into_native()
476    }
477}
478
479impl IntoBytes for DeleteAgentAction {
480    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
481        let proto = self.into_proto()?;
482        let bytes = proto.write_to_bytes().map_err(|_| {
483            ProtoConversionError::SerializationError(
484                "Unable to get bytes from DeleteAgentAction".to_string(),
485            )
486        })?;
487        Ok(bytes)
488    }
489}
490
491impl IntoProto<protos::pike_payload::DeleteAgentAction> for DeleteAgentAction {}
492impl IntoNative<DeleteAgentAction> for protos::pike_payload::DeleteAgentAction {}
493
494/// Native representation of the "create organization" action payload
495#[derive(Debug, Default, Clone, PartialEq)]
496pub struct CreateOrganizationAction {
497    org_id: String,
498    name: String,
499    alternate_ids: Vec<AlternateId>,
500    metadata: Vec<KeyValueEntry>,
501}
502
503impl CreateOrganizationAction {
504    pub fn org_id(&self) -> &str {
505        &self.org_id
506    }
507
508    pub fn name(&self) -> &str {
509        &self.name
510    }
511
512    pub fn alternate_ids(&self) -> &[AlternateId] {
513        &self.alternate_ids
514    }
515
516    pub fn metadata(&self) -> &[KeyValueEntry] {
517        &self.metadata
518    }
519}
520
521impl FromProto<protos::pike_payload::CreateOrganizationAction> for CreateOrganizationAction {
522    fn from_proto(
523        create_org: protos::pike_payload::CreateOrganizationAction,
524    ) -> Result<Self, ProtoConversionError> {
525        Ok(CreateOrganizationAction {
526            org_id: create_org.get_id().to_string(),
527            name: create_org.get_name().to_string(),
528            alternate_ids: create_org
529                .get_alternate_ids()
530                .iter()
531                .cloned()
532                .map(AlternateId::from_proto)
533                .collect::<Result<Vec<AlternateId>, ProtoConversionError>>()?,
534            metadata: create_org
535                .get_metadata()
536                .iter()
537                .cloned()
538                .map(KeyValueEntry::from_proto)
539                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
540        })
541    }
542}
543
544impl FromNative<CreateOrganizationAction> for protos::pike_payload::CreateOrganizationAction {
545    fn from_native(create_org: CreateOrganizationAction) -> Result<Self, ProtoConversionError> {
546        let mut proto_create_org = protos::pike_payload::CreateOrganizationAction::new();
547
548        proto_create_org.set_id(create_org.org_id().to_string());
549        proto_create_org.set_name(create_org.name().to_string());
550        proto_create_org.set_alternate_ids(RepeatedField::from_vec(
551            create_org
552                .alternate_ids()
553                .iter()
554                .cloned()
555                .map(AlternateId::into_proto)
556                .collect::<Result<Vec<protos::pike_state::AlternateId>, ProtoConversionError>>()?,
557        ));
558        proto_create_org.set_metadata(RepeatedField::from_vec(
559            create_org
560                .metadata()
561                .iter()
562                .cloned()
563                .map(KeyValueEntry::into_proto)
564                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
565                )?,
566        ));
567
568        Ok(proto_create_org)
569    }
570}
571
572impl FromBytes<CreateOrganizationAction> for CreateOrganizationAction {
573    fn from_bytes(bytes: &[u8]) -> Result<CreateOrganizationAction, ProtoConversionError> {
574        let proto: protos::pike_payload::CreateOrganizationAction =
575            Message::parse_from_bytes(bytes).map_err(|_| {
576                ProtoConversionError::SerializationError(
577                    "Unable to get CreateOrganizationAction from bytes".to_string(),
578                )
579            })?;
580        proto.into_native()
581    }
582}
583
584impl IntoBytes for CreateOrganizationAction {
585    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
586        let proto = self.into_proto()?;
587        let bytes = proto.write_to_bytes().map_err(|_| {
588            ProtoConversionError::SerializationError(
589                "Unable to get bytes from CreateOrganizationAction".to_string(),
590            )
591        })?;
592        Ok(bytes)
593    }
594}
595
596impl IntoProto<protos::pike_payload::CreateOrganizationAction> for CreateOrganizationAction {}
597impl IntoNative<CreateOrganizationAction> for protos::pike_payload::CreateOrganizationAction {}
598
599/// Returned if any required fields in a `CreateOrganizationAction` are not present when being
600/// converted from the corresponding builder
601#[derive(Debug)]
602pub enum CreateOrganizationActionBuildError {
603    MissingField(String),
604}
605
606impl StdError for CreateOrganizationActionBuildError {
607    fn description(&self) -> &str {
608        match *self {
609            CreateOrganizationActionBuildError::MissingField(ref msg) => msg,
610        }
611    }
612
613    fn cause(&self) -> Option<&dyn StdError> {
614        match *self {
615            CreateOrganizationActionBuildError::MissingField(_) => None,
616        }
617    }
618}
619
620impl std::fmt::Display for CreateOrganizationActionBuildError {
621    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
622        match *self {
623            CreateOrganizationActionBuildError::MissingField(ref s) => {
624                write!(f, "MissingField: {}", s)
625            }
626        }
627    }
628}
629
630/// Builder used to create a "create organization" action
631#[derive(Default, Clone)]
632pub struct CreateOrganizationActionBuilder {
633    pub org_id: Option<String>,
634    pub name: Option<String>,
635    pub alternate_ids: Vec<AlternateId>,
636    pub metadata: Vec<KeyValueEntry>,
637}
638
639impl CreateOrganizationActionBuilder {
640    pub fn new() -> Self {
641        CreateOrganizationActionBuilder::default()
642    }
643
644    pub fn with_org_id(mut self, org_id: String) -> CreateOrganizationActionBuilder {
645        self.org_id = Some(org_id);
646        self
647    }
648
649    pub fn with_name(mut self, name: String) -> CreateOrganizationActionBuilder {
650        self.name = Some(name);
651        self
652    }
653
654    pub fn with_alternate_ids(
655        mut self,
656        alternate_ids: Vec<AlternateId>,
657    ) -> CreateOrganizationActionBuilder {
658        self.alternate_ids = alternate_ids;
659        self
660    }
661
662    pub fn with_metadata(
663        mut self,
664        metadata: Vec<KeyValueEntry>,
665    ) -> CreateOrganizationActionBuilder {
666        self.metadata = metadata;
667        self
668    }
669
670    pub fn build(self) -> Result<CreateOrganizationAction, CreateOrganizationActionBuildError> {
671        let org_id = self.org_id.ok_or_else(|| {
672            CreateOrganizationActionBuildError::MissingField(
673                "'org_id' field is required".to_string(),
674            )
675        })?;
676
677        let name = self.name.ok_or_else(|| {
678            CreateOrganizationActionBuildError::MissingField("'name' field is required".to_string())
679        })?;
680
681        let alternate_ids = self.alternate_ids;
682
683        let metadata = self.metadata;
684
685        Ok(CreateOrganizationAction {
686            org_id,
687            name,
688            alternate_ids,
689            metadata,
690        })
691    }
692}
693
694/// Native representation of the "update organization" action payload
695#[derive(Debug, Default, Clone, PartialEq)]
696pub struct UpdateOrganizationAction {
697    org_id: String,
698    name: String,
699    locations: Vec<String>,
700    alternate_ids: Vec<AlternateId>,
701    metadata: Vec<KeyValueEntry>,
702}
703
704impl UpdateOrganizationAction {
705    pub fn org_id(&self) -> &str {
706        &self.org_id
707    }
708
709    pub fn name(&self) -> &str {
710        &self.name
711    }
712
713    pub fn locations(&self) -> &[String] {
714        &self.locations
715    }
716
717    pub fn alternate_ids(&self) -> &[AlternateId] {
718        &self.alternate_ids
719    }
720
721    pub fn metadata(&self) -> &[KeyValueEntry] {
722        &self.metadata
723    }
724}
725
726impl FromProto<protos::pike_payload::UpdateOrganizationAction> for UpdateOrganizationAction {
727    fn from_proto(
728        create_org: protos::pike_payload::UpdateOrganizationAction,
729    ) -> Result<Self, ProtoConversionError> {
730        Ok(UpdateOrganizationAction {
731            org_id: create_org.get_id().to_string(),
732            name: create_org.get_name().to_string(),
733            locations: create_org.get_locations().to_vec(),
734            alternate_ids: create_org
735                .get_alternate_ids()
736                .iter()
737                .cloned()
738                .map(AlternateId::from_proto)
739                .collect::<Result<Vec<AlternateId>, ProtoConversionError>>()?,
740            metadata: create_org
741                .get_metadata()
742                .iter()
743                .cloned()
744                .map(KeyValueEntry::from_proto)
745                .collect::<Result<Vec<KeyValueEntry>, ProtoConversionError>>()?,
746        })
747    }
748}
749
750impl FromNative<UpdateOrganizationAction> for protos::pike_payload::UpdateOrganizationAction {
751    fn from_native(update_org: UpdateOrganizationAction) -> Result<Self, ProtoConversionError> {
752        let mut proto_update_org = protos::pike_payload::UpdateOrganizationAction::new();
753
754        proto_update_org.set_id(update_org.org_id().to_string());
755        proto_update_org.set_name(update_org.name().to_string());
756        proto_update_org.set_locations(RepeatedField::from_vec(update_org.locations().to_vec()));
757        proto_update_org.set_alternate_ids(RepeatedField::from_vec(
758            update_org
759                .alternate_ids()
760                .iter()
761                .cloned()
762                .map(AlternateId::into_proto)
763                .collect::<Result<Vec<protos::pike_state::AlternateId>, ProtoConversionError>>()?,
764        ));
765        proto_update_org.set_metadata(RepeatedField::from_vec(
766            update_org
767                .metadata()
768                .iter()
769                .cloned()
770                .map(KeyValueEntry::into_proto)
771                .collect::<Result<Vec<protos::pike_state::KeyValueEntry>, ProtoConversionError>>(
772                )?,
773        ));
774
775        Ok(proto_update_org)
776    }
777}
778
779impl FromBytes<UpdateOrganizationAction> for UpdateOrganizationAction {
780    fn from_bytes(bytes: &[u8]) -> Result<UpdateOrganizationAction, ProtoConversionError> {
781        let proto: protos::pike_payload::UpdateOrganizationAction =
782            Message::parse_from_bytes(bytes).map_err(|_| {
783                ProtoConversionError::SerializationError(
784                    "Unable to get UpdateOrganizationAction from bytes".to_string(),
785                )
786            })?;
787        proto.into_native()
788    }
789}
790
791impl IntoBytes for UpdateOrganizationAction {
792    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
793        let proto = self.into_proto()?;
794        let bytes = proto.write_to_bytes().map_err(|_| {
795            ProtoConversionError::SerializationError(
796                "Unable to get bytes from UpdateOrganizationAction".to_string(),
797            )
798        })?;
799        Ok(bytes)
800    }
801}
802
803impl IntoProto<protos::pike_payload::UpdateOrganizationAction> for UpdateOrganizationAction {}
804impl IntoNative<UpdateOrganizationAction> for protos::pike_payload::UpdateOrganizationAction {}
805
806/// Returned if any required fields in a `UpdateOrganizationAction` are not present when being
807/// converted from the corresponding builder
808#[derive(Debug)]
809pub enum UpdateOrganizationActionBuildError {
810    MissingField(String),
811}
812
813impl StdError for UpdateOrganizationActionBuildError {
814    fn description(&self) -> &str {
815        match *self {
816            UpdateOrganizationActionBuildError::MissingField(ref msg) => msg,
817        }
818    }
819
820    fn cause(&self) -> Option<&dyn StdError> {
821        match *self {
822            UpdateOrganizationActionBuildError::MissingField(_) => None,
823        }
824    }
825}
826
827impl std::fmt::Display for UpdateOrganizationActionBuildError {
828    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
829        match *self {
830            UpdateOrganizationActionBuildError::MissingField(ref s) => {
831                write!(f, "MissingField: {}", s)
832            }
833        }
834    }
835}
836
837/// Builder used to create an "update organization" action
838#[derive(Default, Clone)]
839pub struct UpdateOrganizationActionBuilder {
840    pub org_id: Option<String>,
841    pub name: Option<String>,
842    pub locations: Vec<String>,
843    pub alternate_ids: Vec<AlternateId>,
844    pub metadata: Vec<KeyValueEntry>,
845}
846
847impl UpdateOrganizationActionBuilder {
848    pub fn new() -> Self {
849        UpdateOrganizationActionBuilder::default()
850    }
851
852    pub fn with_org_id(mut self, org_id: String) -> UpdateOrganizationActionBuilder {
853        self.org_id = Some(org_id);
854        self
855    }
856
857    pub fn with_name(mut self, name: String) -> UpdateOrganizationActionBuilder {
858        self.name = Some(name);
859        self
860    }
861
862    pub fn with_locations(mut self, locations: Vec<String>) -> UpdateOrganizationActionBuilder {
863        self.locations = locations;
864        self
865    }
866
867    pub fn with_alternate_ids(
868        mut self,
869        alternate_ids: Vec<AlternateId>,
870    ) -> UpdateOrganizationActionBuilder {
871        self.alternate_ids = alternate_ids;
872        self
873    }
874
875    pub fn with_metadata(
876        mut self,
877        metadata: Vec<KeyValueEntry>,
878    ) -> UpdateOrganizationActionBuilder {
879        self.metadata = metadata;
880        self
881    }
882
883    pub fn build(self) -> Result<UpdateOrganizationAction, UpdateOrganizationActionBuildError> {
884        let org_id = self.org_id.ok_or_else(|| {
885            UpdateOrganizationActionBuildError::MissingField(
886                "'org_id' field is required".to_string(),
887            )
888        })?;
889
890        let name = self.name.unwrap_or_default();
891
892        let locations = self.locations;
893
894        let alternate_ids = self.alternate_ids;
895
896        let metadata = self.metadata;
897
898        Ok(UpdateOrganizationAction {
899            org_id,
900            name,
901            locations,
902            alternate_ids,
903            metadata,
904        })
905    }
906}
907
908/// Native representation of the "delete organization" action payload
909#[derive(Debug, Default, Clone, PartialEq)]
910pub struct DeleteOrganizationAction {
911    id: String,
912}
913
914impl DeleteOrganizationAction {
915    pub fn id(&self) -> &str {
916        &self.id
917    }
918}
919
920impl FromProto<protos::pike_payload::DeleteOrganizationAction> for DeleteOrganizationAction {
921    fn from_proto(
922        delete_organization: protos::pike_payload::DeleteOrganizationAction,
923    ) -> Result<Self, ProtoConversionError> {
924        Ok(DeleteOrganizationAction {
925            id: delete_organization.get_id().to_string(),
926        })
927    }
928}
929
930impl FromNative<DeleteOrganizationAction> for protos::pike_payload::DeleteOrganizationAction {
931    fn from_native(
932        delete_organization: DeleteOrganizationAction,
933    ) -> Result<Self, ProtoConversionError> {
934        let mut proto_delete_organization = protos::pike_payload::DeleteOrganizationAction::new();
935
936        proto_delete_organization.set_id(delete_organization.id().to_string());
937
938        Ok(proto_delete_organization)
939    }
940}
941
942impl FromBytes<DeleteOrganizationAction> for DeleteOrganizationAction {
943    fn from_bytes(bytes: &[u8]) -> Result<DeleteOrganizationAction, ProtoConversionError> {
944        let proto: protos::pike_payload::DeleteOrganizationAction =
945            Message::parse_from_bytes(bytes).map_err(|_| {
946                ProtoConversionError::SerializationError(
947                    "Unable to get DeleteOrganizationAction from bytes".to_string(),
948                )
949            })?;
950        proto.into_native()
951    }
952}
953
954impl IntoBytes for DeleteOrganizationAction {
955    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
956        let proto = self.into_proto()?;
957        let bytes = proto.write_to_bytes().map_err(|_| {
958            ProtoConversionError::SerializationError(
959                "Unable to get bytes from DeleteOrganizationAction".to_string(),
960            )
961        })?;
962        Ok(bytes)
963    }
964}
965
966impl IntoProto<protos::pike_payload::DeleteOrganizationAction> for DeleteOrganizationAction {}
967impl IntoNative<DeleteOrganizationAction> for protos::pike_payload::DeleteOrganizationAction {}
968
969/// Returned if any required fields in a `DeleteOrganizationAction` are not present when being
970/// converted from the corresponding builder
971#[derive(Debug)]
972pub enum DeleteOrganizationActionBuildError {
973    MissingField(String),
974}
975
976impl StdError for DeleteOrganizationActionBuildError {
977    fn description(&self) -> &str {
978        match *self {
979            DeleteOrganizationActionBuildError::MissingField(ref msg) => msg,
980        }
981    }
982
983    fn cause(&self) -> Option<&dyn StdError> {
984        match *self {
985            DeleteOrganizationActionBuildError::MissingField(_) => None,
986        }
987    }
988}
989
990impl std::fmt::Display for DeleteOrganizationActionBuildError {
991    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
992        match *self {
993            DeleteOrganizationActionBuildError::MissingField(ref s) => {
994                write!(f, "MissingField: {}", s)
995            }
996        }
997    }
998}
999
1000/// Builder used to create a "delete organization" action
1001#[derive(Default, Clone)]
1002pub struct DeleteOrganizationActionBuilder {
1003    pub id: Option<String>,
1004}
1005
1006impl DeleteOrganizationActionBuilder {
1007    pub fn new() -> Self {
1008        DeleteOrganizationActionBuilder::default()
1009    }
1010
1011    pub fn with_id(mut self, id: String) -> DeleteOrganizationActionBuilder {
1012        self.id = Some(id);
1013        self
1014    }
1015
1016    pub fn build(self) -> Result<DeleteOrganizationAction, DeleteOrganizationActionBuildError> {
1017        let id = self.id.ok_or_else(|| {
1018            DeleteOrganizationActionBuildError::MissingField("'id' field is required".to_string())
1019        })?;
1020
1021        Ok(DeleteOrganizationAction { id })
1022    }
1023}
1024
1025/// Native representation of the "create role" action payload
1026#[derive(Debug, Default, Clone, PartialEq)]
1027pub struct CreateRoleAction {
1028    org_id: String,
1029    name: String,
1030    description: String,
1031    permissions: Vec<String>,
1032    allowed_organizations: Vec<String>,
1033    inherit_from: Vec<String>,
1034    active: bool,
1035}
1036
1037impl CreateRoleAction {
1038    pub fn org_id(&self) -> &str {
1039        &self.org_id
1040    }
1041
1042    pub fn name(&self) -> &str {
1043        &self.name
1044    }
1045
1046    pub fn description(&self) -> &str {
1047        &self.description
1048    }
1049
1050    pub fn permissions(&self) -> &[String] {
1051        &self.permissions
1052    }
1053
1054    pub fn allowed_organizations(&self) -> &[String] {
1055        &self.allowed_organizations
1056    }
1057
1058    pub fn inherit_from(&self) -> &[String] {
1059        &self.inherit_from
1060    }
1061
1062    pub fn active(&self) -> &bool {
1063        &self.active
1064    }
1065}
1066
1067impl FromProto<protos::pike_payload::CreateRoleAction> for CreateRoleAction {
1068    fn from_proto(
1069        create_role: protos::pike_payload::CreateRoleAction,
1070    ) -> Result<Self, ProtoConversionError> {
1071        Ok(CreateRoleAction {
1072            org_id: create_role.get_org_id().to_string(),
1073            name: create_role.get_name().to_string(),
1074            description: create_role.get_description().to_string(),
1075            permissions: create_role.get_permissions().to_vec(),
1076            allowed_organizations: create_role.get_allowed_organizations().to_vec(),
1077            inherit_from: create_role.get_inherit_from().to_vec(),
1078            active: create_role.get_active(),
1079        })
1080    }
1081}
1082
1083impl FromNative<CreateRoleAction> for protos::pike_payload::CreateRoleAction {
1084    fn from_native(create_role: CreateRoleAction) -> Result<Self, ProtoConversionError> {
1085        let mut proto_create_role = protos::pike_payload::CreateRoleAction::new();
1086
1087        proto_create_role.set_org_id(create_role.org_id().to_string());
1088        proto_create_role.set_name(create_role.name().to_string());
1089        proto_create_role.set_description(create_role.description().to_string());
1090        proto_create_role
1091            .set_permissions(RepeatedField::from_vec(create_role.permissions().to_vec()));
1092        proto_create_role.set_allowed_organizations(RepeatedField::from_vec(
1093            create_role.allowed_organizations().to_vec(),
1094        ));
1095        proto_create_role
1096            .set_inherit_from(RepeatedField::from_vec(create_role.inherit_from().to_vec()));
1097        proto_create_role.set_active(*create_role.active());
1098
1099        Ok(proto_create_role)
1100    }
1101}
1102
1103impl FromBytes<CreateRoleAction> for CreateRoleAction {
1104    fn from_bytes(bytes: &[u8]) -> Result<CreateRoleAction, ProtoConversionError> {
1105        let proto: protos::pike_payload::CreateRoleAction = Message::parse_from_bytes(bytes)
1106            .map_err(|_| {
1107                ProtoConversionError::SerializationError(
1108                    "Unable to get CreateRoleAction from bytes".to_string(),
1109                )
1110            })?;
1111        proto.into_native()
1112    }
1113}
1114
1115impl IntoBytes for CreateRoleAction {
1116    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1117        let proto = self.into_proto()?;
1118        let bytes = proto.write_to_bytes().map_err(|_| {
1119            ProtoConversionError::SerializationError(
1120                "Unable to get bytes from CreateRoleAction".to_string(),
1121            )
1122        })?;
1123        Ok(bytes)
1124    }
1125}
1126
1127impl IntoProto<protos::pike_payload::CreateRoleAction> for CreateRoleAction {}
1128impl IntoNative<CreateRoleAction> for protos::pike_payload::CreateRoleAction {}
1129
1130/// Returned if any required fields in a `CreateRoleAction` are not present when being
1131/// converted from the corresponding builder
1132#[derive(Debug)]
1133pub enum CreateRoleActionBuildError {
1134    MissingField(String),
1135}
1136
1137impl StdError for CreateRoleActionBuildError {
1138    fn description(&self) -> &str {
1139        match *self {
1140            CreateRoleActionBuildError::MissingField(ref msg) => msg,
1141        }
1142    }
1143
1144    fn cause(&self) -> Option<&dyn StdError> {
1145        match *self {
1146            CreateRoleActionBuildError::MissingField(_) => None,
1147        }
1148    }
1149}
1150
1151impl std::fmt::Display for CreateRoleActionBuildError {
1152    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1153        match *self {
1154            CreateRoleActionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1155        }
1156    }
1157}
1158
1159/// Builder used to create a "create role" action
1160#[derive(Default, Clone)]
1161pub struct CreateRoleActionBuilder {
1162    pub org_id: Option<String>,
1163    pub name: Option<String>,
1164    pub description: Option<String>,
1165    pub permissions: Vec<String>,
1166    pub allowed_organizations: Vec<String>,
1167    pub inherit_from: Vec<String>,
1168    pub active: Option<bool>,
1169}
1170
1171impl CreateRoleActionBuilder {
1172    pub fn new() -> Self {
1173        CreateRoleActionBuilder::default()
1174    }
1175
1176    pub fn with_org_id(mut self, org_id: String) -> CreateRoleActionBuilder {
1177        self.org_id = Some(org_id);
1178        self
1179    }
1180
1181    pub fn with_name(mut self, name: String) -> CreateRoleActionBuilder {
1182        self.name = Some(name);
1183        self
1184    }
1185
1186    pub fn with_description(mut self, description: String) -> CreateRoleActionBuilder {
1187        self.description = Some(description);
1188        self
1189    }
1190
1191    pub fn with_permissions(mut self, permissions: Vec<String>) -> CreateRoleActionBuilder {
1192        self.permissions = permissions;
1193        self
1194    }
1195
1196    pub fn with_allowed_organizations(
1197        mut self,
1198        allowed_organizations: Vec<String>,
1199    ) -> CreateRoleActionBuilder {
1200        self.allowed_organizations = allowed_organizations;
1201        self
1202    }
1203
1204    pub fn with_inherit_from(mut self, inherit_from: Vec<String>) -> CreateRoleActionBuilder {
1205        self.inherit_from = inherit_from;
1206        self
1207    }
1208
1209    pub fn with_active(mut self, active: bool) -> CreateRoleActionBuilder {
1210        self.active = Some(active);
1211        self
1212    }
1213
1214    pub fn build(self) -> Result<CreateRoleAction, CreateRoleActionBuildError> {
1215        let org_id = self.org_id.ok_or_else(|| {
1216            CreateRoleActionBuildError::MissingField("'org_id' field is required".to_string())
1217        })?;
1218
1219        let name = self.name.ok_or_else(|| {
1220            CreateRoleActionBuildError::MissingField("'name' field is required".to_string())
1221        })?;
1222
1223        let description = self.description.ok_or_else(|| {
1224            CreateRoleActionBuildError::MissingField("'description' field is required".to_string())
1225        })?;
1226
1227        let permissions = self.permissions;
1228
1229        let allowed_organizations = self.allowed_organizations;
1230
1231        let inherit_from = self.inherit_from;
1232
1233        let active = self.active.ok_or_else(|| {
1234            CreateRoleActionBuildError::MissingField("'active' field is required".to_string())
1235        })?;
1236
1237        Ok(CreateRoleAction {
1238            org_id,
1239            name,
1240            description,
1241            permissions,
1242            allowed_organizations,
1243            inherit_from,
1244            active,
1245        })
1246    }
1247}
1248
1249/// Native representation of the "update role" action payload
1250#[derive(Debug, Default, Clone, PartialEq)]
1251pub struct UpdateRoleAction {
1252    org_id: String,
1253    name: String,
1254    description: String,
1255    permissions: Vec<String>,
1256    allowed_organizations: Vec<String>,
1257    inherit_from: Vec<String>,
1258    active: bool,
1259}
1260
1261impl UpdateRoleAction {
1262    pub fn org_id(&self) -> &str {
1263        &self.org_id
1264    }
1265
1266    pub fn name(&self) -> &str {
1267        &self.name
1268    }
1269
1270    pub fn description(&self) -> &str {
1271        &self.description
1272    }
1273
1274    pub fn permissions(&self) -> &[String] {
1275        &self.permissions
1276    }
1277
1278    pub fn allowed_organizations(&self) -> &[String] {
1279        &self.allowed_organizations
1280    }
1281
1282    pub fn inherit_from(&self) -> &[String] {
1283        &self.inherit_from
1284    }
1285
1286    pub fn active(&self) -> &bool {
1287        &self.active
1288    }
1289}
1290
1291impl FromProto<protos::pike_payload::UpdateRoleAction> for UpdateRoleAction {
1292    fn from_proto(
1293        update_role: protos::pike_payload::UpdateRoleAction,
1294    ) -> Result<Self, ProtoConversionError> {
1295        Ok(UpdateRoleAction {
1296            org_id: update_role.get_org_id().to_string(),
1297            name: update_role.get_name().to_string(),
1298            description: update_role.get_description().to_string(),
1299            permissions: update_role.get_permissions().to_vec(),
1300            allowed_organizations: update_role.get_allowed_organizations().to_vec(),
1301            inherit_from: update_role.get_inherit_from().to_vec(),
1302            active: update_role.get_active(),
1303        })
1304    }
1305}
1306
1307impl FromNative<UpdateRoleAction> for protos::pike_payload::UpdateRoleAction {
1308    fn from_native(update_role: UpdateRoleAction) -> Result<Self, ProtoConversionError> {
1309        let mut proto_update_role = protos::pike_payload::UpdateRoleAction::new();
1310
1311        proto_update_role.set_org_id(update_role.org_id().to_string());
1312        proto_update_role.set_name(update_role.name().to_string());
1313        proto_update_role.set_description(update_role.description().to_string());
1314        proto_update_role
1315            .set_permissions(RepeatedField::from_vec(update_role.permissions().to_vec()));
1316        proto_update_role.set_allowed_organizations(RepeatedField::from_vec(
1317            update_role.allowed_organizations().to_vec(),
1318        ));
1319        proto_update_role
1320            .set_inherit_from(RepeatedField::from_vec(update_role.inherit_from().to_vec()));
1321        proto_update_role.set_active(*update_role.active());
1322
1323        Ok(proto_update_role)
1324    }
1325}
1326
1327impl FromBytes<UpdateRoleAction> for UpdateRoleAction {
1328    fn from_bytes(bytes: &[u8]) -> Result<UpdateRoleAction, ProtoConversionError> {
1329        let proto: protos::pike_payload::UpdateRoleAction = Message::parse_from_bytes(bytes)
1330            .map_err(|_| {
1331                ProtoConversionError::SerializationError(
1332                    "Unable to get UpdateRoleAction from bytes".to_string(),
1333                )
1334            })?;
1335        proto.into_native()
1336    }
1337}
1338
1339impl IntoBytes for UpdateRoleAction {
1340    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1341        let proto = self.into_proto()?;
1342        let bytes = proto.write_to_bytes().map_err(|_| {
1343            ProtoConversionError::SerializationError(
1344                "Unable to get bytes from UpdateRoleAction".to_string(),
1345            )
1346        })?;
1347        Ok(bytes)
1348    }
1349}
1350
1351impl IntoProto<protos::pike_payload::UpdateRoleAction> for UpdateRoleAction {}
1352impl IntoNative<UpdateRoleAction> for protos::pike_payload::UpdateRoleAction {}
1353
1354/// Returned if any required fields in an `UpdateRoleAction` are not present when being
1355/// converted from the corresponding builder
1356#[derive(Debug)]
1357pub enum UpdateRoleActionBuildError {
1358    MissingField(String),
1359}
1360
1361impl StdError for UpdateRoleActionBuildError {
1362    fn description(&self) -> &str {
1363        match *self {
1364            UpdateRoleActionBuildError::MissingField(ref msg) => msg,
1365        }
1366    }
1367
1368    fn cause(&self) -> Option<&dyn StdError> {
1369        match *self {
1370            UpdateRoleActionBuildError::MissingField(_) => None,
1371        }
1372    }
1373}
1374
1375impl std::fmt::Display for UpdateRoleActionBuildError {
1376    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1377        match *self {
1378            UpdateRoleActionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1379        }
1380    }
1381}
1382
1383/// Builder used to create a "update role" action
1384#[derive(Default, Clone)]
1385pub struct UpdateRoleActionBuilder {
1386    pub org_id: Option<String>,
1387    pub name: Option<String>,
1388    pub description: Option<String>,
1389    pub permissions: Vec<String>,
1390    pub allowed_organizations: Vec<String>,
1391    pub inherit_from: Vec<String>,
1392    pub active: Option<bool>,
1393}
1394
1395impl UpdateRoleActionBuilder {
1396    pub fn new() -> Self {
1397        UpdateRoleActionBuilder::default()
1398    }
1399
1400    pub fn with_org_id(mut self, org_id: String) -> UpdateRoleActionBuilder {
1401        self.org_id = Some(org_id);
1402        self
1403    }
1404
1405    pub fn with_name(mut self, name: String) -> UpdateRoleActionBuilder {
1406        self.name = Some(name);
1407        self
1408    }
1409
1410    pub fn with_description(mut self, description: String) -> UpdateRoleActionBuilder {
1411        self.description = Some(description);
1412        self
1413    }
1414
1415    pub fn with_permissions(mut self, permissions: Vec<String>) -> UpdateRoleActionBuilder {
1416        self.permissions = permissions;
1417        self
1418    }
1419
1420    pub fn with_allowed_organizations(
1421        mut self,
1422        allowed_organizations: Vec<String>,
1423    ) -> UpdateRoleActionBuilder {
1424        self.allowed_organizations = allowed_organizations;
1425        self
1426    }
1427
1428    pub fn with_inherit_from(mut self, inherit_from: Vec<String>) -> UpdateRoleActionBuilder {
1429        self.inherit_from = inherit_from;
1430        self
1431    }
1432
1433    pub fn with_active(mut self, active: bool) -> UpdateRoleActionBuilder {
1434        self.active = Some(active);
1435        self
1436    }
1437
1438    pub fn build(self) -> Result<UpdateRoleAction, UpdateRoleActionBuildError> {
1439        let org_id = self.org_id.ok_or_else(|| {
1440            UpdateRoleActionBuildError::MissingField("'org_id' field is required".to_string())
1441        })?;
1442
1443        let name = self.name.ok_or_else(|| {
1444            UpdateRoleActionBuildError::MissingField("'name' field is required".to_string())
1445        })?;
1446
1447        let description = self.description.ok_or_else(|| {
1448            UpdateRoleActionBuildError::MissingField("'description' field is required".to_string())
1449        })?;
1450
1451        let permissions = self.permissions;
1452
1453        let allowed_organizations = self.allowed_organizations;
1454
1455        let inherit_from = self.inherit_from;
1456
1457        let active = self.active.ok_or_else(|| {
1458            UpdateRoleActionBuildError::MissingField("'active' field is required".to_string())
1459        })?;
1460
1461        Ok(UpdateRoleAction {
1462            org_id,
1463            name,
1464            description,
1465            permissions,
1466            allowed_organizations,
1467            inherit_from,
1468            active,
1469        })
1470    }
1471}
1472
1473/// Native representation of the "delete role" action payload
1474#[derive(Debug, Default, Clone, PartialEq)]
1475pub struct DeleteRoleAction {
1476    org_id: String,
1477    name: String,
1478}
1479
1480impl DeleteRoleAction {
1481    pub fn org_id(&self) -> &str {
1482        &self.org_id
1483    }
1484
1485    pub fn name(&self) -> &str {
1486        &self.name
1487    }
1488}
1489
1490impl FromProto<protos::pike_payload::DeleteRoleAction> for DeleteRoleAction {
1491    fn from_proto(
1492        delete_role: protos::pike_payload::DeleteRoleAction,
1493    ) -> Result<Self, ProtoConversionError> {
1494        Ok(DeleteRoleAction {
1495            org_id: delete_role.get_org_id().to_string(),
1496            name: delete_role.get_name().to_string(),
1497        })
1498    }
1499}
1500
1501impl FromNative<DeleteRoleAction> for protos::pike_payload::DeleteRoleAction {
1502    fn from_native(delete_role: DeleteRoleAction) -> Result<Self, ProtoConversionError> {
1503        let mut proto_delete_role = protos::pike_payload::DeleteRoleAction::new();
1504
1505        proto_delete_role.set_org_id(delete_role.org_id().to_string());
1506        proto_delete_role.set_name(delete_role.name().to_string());
1507
1508        Ok(proto_delete_role)
1509    }
1510}
1511
1512impl FromBytes<DeleteRoleAction> for DeleteRoleAction {
1513    fn from_bytes(bytes: &[u8]) -> Result<DeleteRoleAction, ProtoConversionError> {
1514        let proto: protos::pike_payload::DeleteRoleAction = Message::parse_from_bytes(bytes)
1515            .map_err(|_| {
1516                ProtoConversionError::SerializationError(
1517                    "Unable to get DeleteRoleAction from bytes".to_string(),
1518                )
1519            })?;
1520        proto.into_native()
1521    }
1522}
1523
1524impl IntoBytes for DeleteRoleAction {
1525    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1526        let proto = self.into_proto()?;
1527        let bytes = proto.write_to_bytes().map_err(|_| {
1528            ProtoConversionError::SerializationError(
1529                "Unable to get bytes from DeleteRoleAction".to_string(),
1530            )
1531        })?;
1532        Ok(bytes)
1533    }
1534}
1535
1536impl IntoProto<protos::pike_payload::DeleteRoleAction> for DeleteRoleAction {}
1537impl IntoNative<DeleteRoleAction> for protos::pike_payload::DeleteRoleAction {}
1538
1539/// Returned if any required fields in a `DeleteRoleAction` are not present when being
1540/// converted from the corresponding builder
1541#[derive(Debug)]
1542pub enum DeleteRoleActionBuildError {
1543    MissingField(String),
1544}
1545
1546impl StdError for DeleteRoleActionBuildError {
1547    fn description(&self) -> &str {
1548        match *self {
1549            DeleteRoleActionBuildError::MissingField(ref msg) => msg,
1550        }
1551    }
1552
1553    fn cause(&self) -> Option<&dyn StdError> {
1554        match *self {
1555            DeleteRoleActionBuildError::MissingField(_) => None,
1556        }
1557    }
1558}
1559
1560impl std::fmt::Display for DeleteRoleActionBuildError {
1561    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1562        match *self {
1563            DeleteRoleActionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1564        }
1565    }
1566}
1567
1568/// Builder used to create a "delete role" action
1569#[derive(Default, Clone)]
1570pub struct DeleteRoleActionBuilder {
1571    pub org_id: Option<String>,
1572    pub name: Option<String>,
1573}
1574
1575impl DeleteRoleActionBuilder {
1576    pub fn new() -> Self {
1577        DeleteRoleActionBuilder::default()
1578    }
1579
1580    pub fn with_org_id(mut self, org_id: String) -> DeleteRoleActionBuilder {
1581        self.org_id = Some(org_id);
1582        self
1583    }
1584
1585    pub fn with_name(mut self, name: String) -> DeleteRoleActionBuilder {
1586        self.name = Some(name);
1587        self
1588    }
1589
1590    pub fn build(self) -> Result<DeleteRoleAction, DeleteRoleActionBuildError> {
1591        let org_id = self.org_id.ok_or_else(|| {
1592            DeleteRoleActionBuildError::MissingField("'org_id' field is required".to_string())
1593        })?;
1594
1595        let name = self.name.ok_or_else(|| {
1596            DeleteRoleActionBuildError::MissingField("'name' field is required".to_string())
1597        })?;
1598
1599        Ok(DeleteRoleAction { org_id, name })
1600    }
1601}
1602
1603/// Native representation of a Pike transaction payload
1604#[derive(Debug, Clone, PartialEq)]
1605pub struct PikePayload {
1606    action: Action,
1607    timestamp: u64,
1608}
1609
1610impl PikePayload {
1611    pub fn action(&self) -> &Action {
1612        &self.action
1613    }
1614
1615    pub fn timestamp(&self) -> u64 {
1616        self.timestamp
1617    }
1618}
1619
1620impl FromProto<protos::pike_payload::PikePayload> for PikePayload {
1621    fn from_proto(
1622        payload: protos::pike_payload::PikePayload,
1623    ) -> Result<Self, ProtoConversionError> {
1624        let action = match payload.get_action() {
1625            protos::pike_payload::PikePayload_Action::CREATE_AGENT => Action::CreateAgent(
1626                CreateAgentAction::from_proto(payload.get_create_agent().clone())?,
1627            ),
1628            protos::pike_payload::PikePayload_Action::UPDATE_AGENT => Action::UpdateAgent(
1629                UpdateAgentAction::from_proto(payload.get_update_agent().clone())?,
1630            ),
1631            protos::pike_payload::PikePayload_Action::DELETE_AGENT => Action::DeleteAgent(
1632                DeleteAgentAction::from_proto(payload.get_delete_agent().clone())?,
1633            ),
1634            protos::pike_payload::PikePayload_Action::CREATE_ORGANIZATION => {
1635                Action::CreateOrganization(CreateOrganizationAction::from_proto(
1636                    payload.get_create_organization().clone(),
1637                )?)
1638            }
1639            protos::pike_payload::PikePayload_Action::UPDATE_ORGANIZATION => {
1640                Action::UpdateOrganization(UpdateOrganizationAction::from_proto(
1641                    payload.get_update_organization().clone(),
1642                )?)
1643            }
1644            protos::pike_payload::PikePayload_Action::DELETE_ORGANIZATION => {
1645                Action::DeleteOrganization(DeleteOrganizationAction::from_proto(
1646                    payload.get_delete_organization().clone(),
1647                )?)
1648            }
1649            protos::pike_payload::PikePayload_Action::CREATE_ROLE => Action::CreateRole(
1650                CreateRoleAction::from_proto(payload.get_create_role().clone())?,
1651            ),
1652            protos::pike_payload::PikePayload_Action::UPDATE_ROLE => Action::UpdateRole(
1653                UpdateRoleAction::from_proto(payload.get_update_role().clone())?,
1654            ),
1655            protos::pike_payload::PikePayload_Action::DELETE_ROLE => Action::DeleteRole(
1656                DeleteRoleAction::from_proto(payload.get_delete_role().clone())?,
1657            ),
1658            protos::pike_payload::PikePayload_Action::ACTION_UNSET => {
1659                return Err(ProtoConversionError::InvalidTypeError(
1660                    "Cannot convert PikePayload_Action with type unset.".to_string(),
1661                ));
1662            }
1663        };
1664
1665        let timestamp = payload.get_timestamp();
1666
1667        Ok(Self { action, timestamp })
1668    }
1669}
1670
1671impl FromNative<PikePayload> for protos::pike_payload::PikePayload {
1672    fn from_native(native: PikePayload) -> Result<Self, ProtoConversionError> {
1673        let mut proto = protos::pike_payload::PikePayload::new();
1674        proto.set_timestamp(native.timestamp());
1675
1676        match native.action() {
1677            Action::CreateAgent(payload) => {
1678                proto.set_action(protos::pike_payload::PikePayload_Action::CREATE_AGENT);
1679                proto.set_create_agent(payload.clone().into_proto()?);
1680            }
1681            Action::UpdateAgent(payload) => {
1682                proto.set_action(protos::pike_payload::PikePayload_Action::UPDATE_AGENT);
1683                proto.set_update_agent(payload.clone().into_proto()?);
1684            }
1685            Action::DeleteAgent(payload) => {
1686                proto.set_action(protos::pike_payload::PikePayload_Action::DELETE_AGENT);
1687                proto.set_delete_agent(payload.clone().into_proto()?);
1688            }
1689            Action::CreateOrganization(payload) => {
1690                proto.set_action(protos::pike_payload::PikePayload_Action::CREATE_ORGANIZATION);
1691                proto.set_create_organization(payload.clone().into_proto()?);
1692            }
1693            Action::UpdateOrganization(payload) => {
1694                proto.set_action(protos::pike_payload::PikePayload_Action::UPDATE_ORGANIZATION);
1695                proto.set_update_organization(payload.clone().into_proto()?);
1696            }
1697            Action::DeleteOrganization(payload) => {
1698                proto.set_action(protos::pike_payload::PikePayload_Action::DELETE_ORGANIZATION);
1699                proto.set_delete_organization(payload.clone().into_proto()?);
1700            }
1701            Action::CreateRole(payload) => {
1702                proto.set_action(protos::pike_payload::PikePayload_Action::CREATE_ROLE);
1703                proto.set_create_role(payload.clone().into_proto()?);
1704            }
1705            Action::UpdateRole(payload) => {
1706                proto.set_action(protos::pike_payload::PikePayload_Action::UPDATE_ROLE);
1707                proto.set_update_role(payload.clone().into_proto()?);
1708            }
1709            Action::DeleteRole(payload) => {
1710                proto.set_action(protos::pike_payload::PikePayload_Action::DELETE_ROLE);
1711                proto.set_delete_role(payload.clone().into_proto()?);
1712            }
1713        };
1714
1715        Ok(proto)
1716    }
1717}
1718
1719impl FromBytes<PikePayload> for PikePayload {
1720    fn from_bytes(bytes: &[u8]) -> Result<PikePayload, ProtoConversionError> {
1721        let proto: protos::pike_payload::PikePayload =
1722            Message::parse_from_bytes(bytes).map_err(|_| {
1723                ProtoConversionError::SerializationError(
1724                    "Unable to get PikePayload from bytes".to_string(),
1725                )
1726            })?;
1727        proto.into_native()
1728    }
1729}
1730
1731impl IntoBytes for PikePayload {
1732    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1733        let proto = self.into_proto()?;
1734        let bytes = proto.write_to_bytes().map_err(|_| {
1735            ProtoConversionError::SerializationError(
1736                "Unable to get bytes from PikePayload".to_string(),
1737            )
1738        })?;
1739        Ok(bytes)
1740    }
1741}
1742
1743impl IntoProto<protos::pike_payload::PikePayload> for PikePayload {}
1744impl IntoNative<PikePayload> for protos::pike_payload::PikePayload {}
1745
1746/// Returned if any required fields in a `PikePayload` are not present when being
1747/// converted from the corresponding builder
1748#[derive(Debug)]
1749pub enum PikePayloadBuildError {
1750    MissingField(String),
1751}
1752
1753impl StdError for PikePayloadBuildError {
1754    fn description(&self) -> &str {
1755        match *self {
1756            PikePayloadBuildError::MissingField(ref msg) => msg,
1757        }
1758    }
1759
1760    fn cause(&self) -> Option<&dyn StdError> {
1761        match *self {
1762            PikePayloadBuildError::MissingField(_) => None,
1763        }
1764    }
1765}
1766
1767impl std::fmt::Display for PikePayloadBuildError {
1768    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1769        match *self {
1770            PikePayloadBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1771        }
1772    }
1773}
1774
1775/// Builder used to create a Pike transaction payload
1776#[derive(Default, Clone)]
1777pub struct PikePayloadBuilder {
1778    pub action: Option<Action>,
1779    pub timestamp: Option<u64>,
1780}
1781
1782impl PikePayloadBuilder {
1783    pub fn new() -> Self {
1784        PikePayloadBuilder::default()
1785    }
1786
1787    pub fn with_action(mut self, action: Action) -> PikePayloadBuilder {
1788        self.action = Some(action);
1789        self
1790    }
1791
1792    pub fn with_timestamp(mut self, timestamp: u64) -> Self {
1793        self.timestamp = Some(timestamp);
1794        self
1795    }
1796
1797    pub fn build(self) -> Result<PikePayload, PikePayloadBuildError> {
1798        let action = self.action.ok_or_else(|| {
1799            PikePayloadBuildError::MissingField("'action' field is required".to_string())
1800        })?;
1801
1802        let timestamp = self.timestamp.ok_or_else(|| {
1803            PikePayloadBuildError::MissingField("'timestamp' field is required".into())
1804        })?;
1805
1806        Ok(PikePayload { action, timestamp })
1807    }
1808}
1809
1810#[cfg(test)]
1811mod tests {
1812    use super::*;
1813
1814    use crate::protocol::pike::state::KeyValueEntryBuilder;
1815
1816    #[test]
1817    /// Validate that a `CreateAgentAction` is built correctly
1818    fn check_create_agent_action() {
1819        let builder = KeyValueEntryBuilder::new();
1820        let key_value = builder
1821            .with_key("Key".to_string())
1822            .with_value("Value".to_string())
1823            .build()
1824            .unwrap();
1825
1826        let builder = CreateAgentActionBuilder::new();
1827        let create_agent = builder
1828            .with_org_id("organization".to_string())
1829            .with_public_key("public_key".to_string())
1830            .with_active(true)
1831            .with_roles(vec!["Role".to_string()])
1832            .with_metadata(vec![key_value.clone()])
1833            .build()
1834            .unwrap();
1835
1836        assert_eq!(create_agent.org_id(), "organization");
1837        assert_eq!(create_agent.public_key(), "public_key");
1838        assert!(create_agent.active());
1839        assert_eq!(create_agent.roles(), ["Role".to_string()]);
1840        assert_eq!(create_agent.metadata(), [key_value]);
1841    }
1842
1843    #[test]
1844    /// Validate that a `CreateAgentAction` may be converted into bytes and back into its
1845    /// native representation
1846    fn check_create_agent_bytes() {
1847        let builder = KeyValueEntryBuilder::new();
1848        let key_value = builder
1849            .with_key("Key".to_string())
1850            .with_value("Value".to_string())
1851            .build()
1852            .unwrap();
1853
1854        let builder = CreateAgentActionBuilder::new();
1855        let original = builder
1856            .with_org_id("organization".to_string())
1857            .with_public_key("public_key".to_string())
1858            .with_active(true)
1859            .with_roles(vec!["Role".to_string()])
1860            .with_metadata(vec![key_value.clone()])
1861            .build()
1862            .unwrap();
1863
1864        let bytes = original.clone().into_bytes().unwrap();
1865        let create_agent = CreateAgentAction::from_bytes(&bytes).unwrap();
1866        assert_eq!(create_agent, original);
1867    }
1868
1869    #[test]
1870    /// Validate that an `UpdateAgentAction` is built correctly
1871    fn check_update_agent_action() {
1872        let builder = KeyValueEntryBuilder::new();
1873        let key_value = builder
1874            .with_key("Key".to_string())
1875            .with_value("Value".to_string())
1876            .build()
1877            .unwrap();
1878
1879        let builder = UpdateAgentActionBuilder::new();
1880        let update_agent = builder
1881            .with_org_id("organization".to_string())
1882            .with_public_key("public_key".to_string())
1883            .with_active(true)
1884            .with_roles(vec!["Role".to_string()])
1885            .with_metadata(vec![key_value.clone()])
1886            .build()
1887            .unwrap();
1888
1889        assert_eq!(update_agent.org_id(), "organization");
1890        assert_eq!(update_agent.public_key(), "public_key");
1891        assert!(update_agent.active());
1892        assert_eq!(update_agent.roles(), ["Role".to_string()]);
1893        assert_eq!(update_agent.metadata(), [key_value]);
1894    }
1895
1896    #[test]
1897    /// Validate that an `UpdateAgentAction` may be correctly converted to bytes and back to its
1898    /// native representation
1899    fn check_update_agent_bytes() {
1900        let builder = KeyValueEntryBuilder::new();
1901        let key_value = builder
1902            .with_key("Key".to_string())
1903            .with_value("Value".to_string())
1904            .build()
1905            .unwrap();
1906
1907        let builder = UpdateAgentActionBuilder::new();
1908        let original = builder
1909            .with_org_id("organization".to_string())
1910            .with_public_key("public_key".to_string())
1911            .with_active(true)
1912            .with_roles(vec!["Role".to_string()])
1913            .with_metadata(vec![key_value.clone()])
1914            .build()
1915            .unwrap();
1916
1917        let bytes = original.clone().into_bytes().unwrap();
1918        let update_agent = UpdateAgentAction::from_bytes(&bytes).unwrap();
1919        assert_eq!(update_agent, original);
1920    }
1921
1922    #[test]
1923    /// Validate that a `CreateOrganizationAction` is built correctly
1924    fn check_create_organization_builder() {
1925        let builder = KeyValueEntryBuilder::new();
1926        let key_value = builder
1927            .with_key("Key".to_string())
1928            .with_value("Value".to_string())
1929            .build()
1930            .unwrap();
1931
1932        let builder = CreateOrganizationActionBuilder::new();
1933        let create_organization = builder
1934            .with_org_id("organization".to_string())
1935            .with_name("name".to_string())
1936            .with_metadata(vec![key_value.clone()])
1937            .build()
1938            .unwrap();
1939
1940        assert_eq!(create_organization.org_id(), "organization");
1941        assert_eq!(create_organization.name(), "name");
1942        assert_eq!(create_organization.metadata(), [key_value]);
1943    }
1944
1945    #[test]
1946    /// Validate that a `CreateAgentAction` may be correctly converted into bytes and back to its
1947    /// native representation
1948    fn check_create_organization_bytes() {
1949        let builder = KeyValueEntryBuilder::new();
1950        let key_value = builder
1951            .with_key("Key".to_string())
1952            .with_value("Value".to_string())
1953            .build()
1954            .unwrap();
1955
1956        let builder = CreateOrganizationActionBuilder::new();
1957        let original = builder
1958            .with_org_id("organization".to_string())
1959            .with_name("name".to_string())
1960            .with_metadata(vec![key_value.clone()])
1961            .build()
1962            .unwrap();
1963
1964        let bytes = original.clone().into_bytes().unwrap();
1965        let org = CreateOrganizationAction::from_bytes(&bytes).unwrap();
1966        assert_eq!(org, original);
1967    }
1968
1969    #[test]
1970    /// Validate that an `UpdateOrganizationAction` is built correctly
1971    fn check_update_organization_builder() {
1972        let builder = UpdateOrganizationActionBuilder::new();
1973        let update_organization = builder
1974            .with_org_id("organization".to_string())
1975            .with_name("name".to_string())
1976            .with_locations(vec!["location".to_string()])
1977            .build()
1978            .unwrap();
1979
1980        assert_eq!(update_organization.org_id(), "organization");
1981        assert_eq!(update_organization.name(), "name");
1982        assert_eq!(update_organization.locations(), ["location"]);
1983    }
1984
1985    #[test]
1986    /// Validate that an `UpdateOrganizationAction` may be correctly converted into bytes and back
1987    /// to its native representation
1988    fn check_update_organization_bytes() {
1989        let builder = UpdateOrganizationActionBuilder::new();
1990        let original = builder
1991            .with_org_id("organization".to_string())
1992            .with_name("name".to_string())
1993            .with_locations(vec!["location".to_string()])
1994            .build()
1995            .unwrap();
1996
1997        let bytes = original.clone().into_bytes().unwrap();
1998        let org = UpdateOrganizationAction::from_bytes(&bytes).unwrap();
1999        assert_eq!(org, original);
2000    }
2001
2002    #[test]
2003    /// Validate that a `PikePayload` is built correctly with a `CreateAgentAction`
2004    fn check_pike_create_agent_payload() {
2005        let builder = KeyValueEntryBuilder::new();
2006        let key_value = builder
2007            .with_key("Key".to_string())
2008            .with_value("Value".to_string())
2009            .build()
2010            .unwrap();
2011
2012        let builder = CreateAgentActionBuilder::new();
2013        let action = builder
2014            .with_org_id("organization".to_string())
2015            .with_public_key("public_key".to_string())
2016            .with_active(true)
2017            .with_roles(vec!["Role".to_string()])
2018            .with_metadata(vec![key_value.clone()])
2019            .build()
2020            .unwrap();
2021
2022        let builder = PikePayloadBuilder::new();
2023        let payload = builder
2024            .with_action(Action::CreateAgent(action.clone()))
2025            .with_timestamp(0)
2026            .build()
2027            .unwrap();
2028
2029        let payload = match payload.action {
2030            Action::CreateAgent(payload) => payload,
2031            action => panic!("Invalid action {:?}", action),
2032        };
2033
2034        assert_eq!(payload, action);
2035    }
2036
2037    #[test]
2038    /// Validate that a `PikePayload` is built correctly with an `UpdateAgentAction`
2039    fn check_pike_update_agent_payload() {
2040        let builder = KeyValueEntryBuilder::new();
2041        let key_value = builder
2042            .with_key("Key".to_string())
2043            .with_value("Value".to_string())
2044            .build()
2045            .unwrap();
2046
2047        let builder = UpdateAgentActionBuilder::new();
2048        let action = builder
2049            .with_org_id("organization".to_string())
2050            .with_public_key("public_key".to_string())
2051            .with_active(true)
2052            .with_roles(vec!["Role".to_string()])
2053            .with_metadata(vec![key_value.clone()])
2054            .build()
2055            .unwrap();
2056
2057        let builder = PikePayloadBuilder::new();
2058
2059        let payload = builder
2060            .with_action(Action::UpdateAgent(action.clone()))
2061            .with_timestamp(0)
2062            .build()
2063            .unwrap();
2064
2065        let payload = match payload.action {
2066            Action::UpdateAgent(payload) => payload,
2067            action => panic!("Invalid action {:?}", action),
2068        };
2069
2070        assert_eq!(payload, action);
2071    }
2072
2073    #[test]
2074    /// Validate that a `PikePayload` is built correctly with a `CreateOrganizationAction`
2075    fn check_pike_create_organization_payload() {
2076        let builder = CreateOrganizationActionBuilder::new();
2077        let action = builder
2078            .with_org_id("organization".to_string())
2079            .with_name("name".to_string())
2080            .build()
2081            .unwrap();
2082
2083        let builder = PikePayloadBuilder::new();
2084        let payload = builder
2085            .with_action(Action::CreateOrganization(action.clone()))
2086            .with_timestamp(0)
2087            .build()
2088            .unwrap();
2089
2090        let payload = match payload.action {
2091            Action::CreateOrganization(payload) => payload,
2092            action => panic!("Invalid action {:?}", action),
2093        };
2094
2095        assert_eq!(payload, action);
2096    }
2097
2098    #[test]
2099    /// Validate that a `PikePayload` is built correctly with a `UpdateOrganizationAction`
2100    fn check_pike_update_organiztion_payload() {
2101        let builder = UpdateOrganizationActionBuilder::new();
2102        let action = builder
2103            .with_org_id("organization".to_string())
2104            .with_name("name".to_string())
2105            .with_locations(vec!["location".to_string()])
2106            .build()
2107            .unwrap();
2108
2109        let builder = PikePayloadBuilder::new();
2110        let payload = builder
2111            .with_action(Action::UpdateOrganization(action.clone()))
2112            .with_timestamp(0)
2113            .build()
2114            .unwrap();
2115
2116        let payload = match payload.action {
2117            Action::UpdateOrganization(payload) => payload,
2118            action => panic!("Invalid action {:?}", action),
2119        };
2120
2121        assert_eq!(payload, action);
2122    }
2123
2124    #[test]
2125    /// Validate that a `PikePayload` may be correctly converted into bytes and back to its
2126    /// native representation.
2127    fn check_pike_payload_bytes() {
2128        let builder = UpdateOrganizationActionBuilder::new();
2129        let action = builder
2130            .with_org_id("organization".to_string())
2131            .with_name("name".to_string())
2132            .with_locations(vec!["location".to_string()])
2133            .build()
2134            .unwrap();
2135
2136        let builder = PikePayloadBuilder::new();
2137        let original = builder
2138            .with_action(Action::UpdateOrganization(action))
2139            .with_timestamp(0)
2140            .build()
2141            .unwrap();
2142
2143        let bytes = original.clone().into_bytes().unwrap();
2144        let payload = PikePayload::from_bytes(&bytes).unwrap();
2145        assert_eq!(payload, original);
2146    }
2147}