1use super::errors::BuilderError;
18use crate::protocol::schema::state::{PropertyDefinition, PropertyValue};
19use crate::protos::track_and_trace_state;
20use crate::protos::{
21 FromBytes, FromNative, FromProto, IntoBytes, IntoNative, IntoProto, ProtoConversionError,
22};
23use protobuf::Message;
24use protobuf::RepeatedField;
25
26#[derive(Debug, Clone, PartialEq)]
32pub struct Reporter {
33 public_key: String,
34 authorized: bool,
35 index: u32,
36}
37
38impl Reporter {
39 pub fn public_key(&self) -> &str {
40 &self.public_key
41 }
42 pub fn authorized(&self) -> &bool {
43 &self.authorized
44 }
45 pub fn index(&self) -> &u32 {
46 &self.index
47 }
48 pub fn into_builder(self) -> ReporterBuilder {
49 ReporterBuilder::new()
50 .with_public_key(self.public_key)
51 .with_authorized(self.authorized)
52 .with_index(self.index)
53 }
54}
55
56#[derive(Default, Clone)]
58pub struct ReporterBuilder {
59 public_key: Option<String>,
60 authorized: Option<bool>,
61 index: Option<u32>,
62}
63
64impl ReporterBuilder {
65 pub fn new() -> Self {
66 ReporterBuilder::default()
67 }
68 pub fn with_public_key(mut self, value: String) -> Self {
69 self.public_key = Some(value);
70 self
71 }
72 pub fn with_authorized(mut self, value: bool) -> Self {
73 self.authorized = Some(value);
74 self
75 }
76 pub fn with_index(mut self, value: u32) -> Self {
77 self.index = Some(value);
78 self
79 }
80 pub fn build(self) -> Result<Reporter, BuilderError> {
81 let public_key = self
82 .public_key
83 .ok_or_else(|| BuilderError::MissingField("public_key".into()))?;
84 let authorized = self
85 .authorized
86 .ok_or_else(|| BuilderError::MissingField("authorized".into()))?;
87 let index = self
88 .index
89 .ok_or_else(|| BuilderError::MissingField("index".into()))?;
90 Ok(Reporter {
91 public_key,
92 authorized,
93 index,
94 })
95 }
96}
97
98impl FromProto<track_and_trace_state::Property_Reporter> for Reporter {
99 fn from_proto(
100 proto: track_and_trace_state::Property_Reporter,
101 ) -> Result<Self, ProtoConversionError> {
102 Ok(Reporter {
103 public_key: proto.get_public_key().to_string(),
104 authorized: proto.get_authorized(),
105 index: proto.get_index(),
106 })
107 }
108}
109
110impl FromNative<Reporter> for track_and_trace_state::Property_Reporter {
111 fn from_native(native: Reporter) -> Result<Self, ProtoConversionError> {
112 let mut proto = track_and_trace_state::Property_Reporter::new();
113 proto.set_public_key(native.public_key().to_string());
114 proto.set_authorized(*native.authorized());
115 proto.set_index(*native.index());
116
117 Ok(proto)
118 }
119}
120
121impl FromBytes<Reporter> for Reporter {
122 fn from_bytes(bytes: &[u8]) -> Result<Reporter, ProtoConversionError> {
123 let proto: track_and_trace_state::Property_Reporter = Message::parse_from_bytes(bytes)
124 .map_err(|_| {
125 ProtoConversionError::SerializationError("Unable to get Reporter from bytes".into())
126 })?;
127 proto.into_native()
128 }
129}
130impl IntoBytes for Reporter {
131 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
132 let proto = self.into_proto()?;
133 let bytes = proto.write_to_bytes().map_err(|_| {
134 ProtoConversionError::SerializationError("Unable to get Reporter from bytes".into())
135 })?;
136 Ok(bytes)
137 }
138}
139impl IntoProto<track_and_trace_state::Property_Reporter> for Reporter {}
140impl IntoNative<Reporter> for track_and_trace_state::Property_Reporter {}
141
142#[derive(Debug, Clone, PartialEq)]
146pub struct Property {
147 name: String,
148 record_id: String,
149 property_definition: PropertyDefinition,
150 reporters: Vec<Reporter>,
151 current_page: u32,
152 wrapped: bool,
153}
154
155impl Property {
156 pub fn name(&self) -> &str {
157 &self.name
158 }
159 pub fn record_id(&self) -> &str {
160 &self.record_id
161 }
162 pub fn property_definition(&self) -> &PropertyDefinition {
163 &self.property_definition
164 }
165 pub fn reporters(&self) -> &[Reporter] {
166 &self.reporters
167 }
168 pub fn current_page(&self) -> &u32 {
169 &self.current_page
170 }
171 pub fn wrapped(&self) -> &bool {
172 &self.wrapped
173 }
174
175 pub fn into_builder(self) -> PropertyBuilder {
176 PropertyBuilder::new()
177 .with_name(self.name)
178 .with_record_id(self.record_id)
179 .with_property_definition(self.property_definition)
180 .with_reporters(self.reporters)
181 .with_current_page(self.current_page)
182 .with_wrapped(self.wrapped)
183 }
184}
185
186#[derive(Default, Debug)]
188pub struct PropertyBuilder {
189 name: Option<String>,
190 record_id: Option<String>,
191 property_definition: Option<PropertyDefinition>,
192 reporters: Option<Vec<Reporter>>,
193 current_page: Option<u32>,
194 wrapped: Option<bool>,
195}
196
197impl PropertyBuilder {
198 pub fn new() -> Self {
199 PropertyBuilder::default()
200 }
201 pub fn with_name(mut self, value: String) -> Self {
202 self.name = Some(value);
203 self
204 }
205 pub fn with_record_id(mut self, value: String) -> Self {
206 self.record_id = Some(value);
207 self
208 }
209 pub fn with_property_definition(mut self, value: PropertyDefinition) -> Self {
210 self.property_definition = Some(value);
211 self
212 }
213 pub fn with_reporters(mut self, value: Vec<Reporter>) -> Self {
214 self.reporters = Some(value);
215 self
216 }
217 pub fn with_current_page(mut self, value: u32) -> Self {
218 self.current_page = Some(value);
219 self
220 }
221 pub fn with_wrapped(mut self, value: bool) -> Self {
222 self.wrapped = Some(value);
223 self
224 }
225 pub fn build(self) -> Result<Property, BuilderError> {
226 let name = self
227 .name
228 .ok_or_else(|| BuilderError::MissingField("name".into()))?;
229 let record_id = self
230 .record_id
231 .ok_or_else(|| BuilderError::MissingField("record_id".into()))?;
232 let property_definition = self
233 .property_definition
234 .ok_or_else(|| BuilderError::MissingField("property_definition".into()))?;
235 let reporters = self
236 .reporters
237 .ok_or_else(|| BuilderError::MissingField("reporters".into()))?;
238 let current_page = self
239 .current_page
240 .ok_or_else(|| BuilderError::MissingField("current_page".into()))?;
241 let wrapped = self
242 .wrapped
243 .ok_or_else(|| BuilderError::MissingField("wrapped".into()))?;
244 Ok(Property {
245 name,
246 record_id,
247 property_definition,
248 reporters,
249 current_page,
250 wrapped,
251 })
252 }
253}
254
255impl FromProto<track_and_trace_state::Property> for Property {
256 fn from_proto(proto: track_and_trace_state::Property) -> Result<Self, ProtoConversionError> {
257 Ok(Property {
258 name: proto.get_name().to_string(),
259 record_id: proto.get_record_id().to_string(),
260 property_definition: PropertyDefinition::from_proto(
261 proto.get_property_definition().clone(),
262 )?,
263 reporters: proto
264 .get_reporters()
265 .iter()
266 .cloned()
267 .map(Reporter::from_proto)
268 .collect::<Result<Vec<Reporter>, ProtoConversionError>>()?,
269 current_page: proto.get_current_page(),
270 wrapped: proto.get_wrapped(),
271 })
272 }
273}
274
275impl FromNative<Property> for track_and_trace_state::Property {
276 fn from_native(native: Property) -> Result<Self, ProtoConversionError> {
277 let mut proto = track_and_trace_state::Property::new();
278 proto.set_name(native.name().to_string());
279 proto.set_record_id(native.record_id().to_string());
280 proto.set_property_definition(native.property_definition().clone().into_proto()?);
281 proto.set_reporters(RepeatedField::from_vec(
282 native.reporters()
283 .iter()
284 .cloned()
285 .map(Reporter::into_proto)
286 .collect::<Result<Vec<track_and_trace_state::Property_Reporter>, ProtoConversionError>>()?));
287 proto.set_current_page(*native.current_page());
288 proto.set_wrapped(*native.wrapped());
289
290 Ok(proto)
291 }
292}
293
294impl FromBytes<Property> for Property {
295 fn from_bytes(bytes: &[u8]) -> Result<Property, ProtoConversionError> {
296 let proto: track_and_trace_state::Property =
297 Message::parse_from_bytes(bytes).map_err(|_| {
298 ProtoConversionError::SerializationError("Unable to get Property from bytes".into())
299 })?;
300 proto.into_native()
301 }
302}
303impl IntoBytes for Property {
304 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
305 let proto = self.into_proto()?;
306 let bytes = proto.write_to_bytes().map_err(|_| {
307 ProtoConversionError::SerializationError("Unable to get Property from bytes".into())
308 })?;
309 Ok(bytes)
310 }
311}
312impl IntoProto<track_and_trace_state::Property> for Property {}
313impl IntoNative<Property> for track_and_trace_state::Property {}
314
315#[derive(Debug, Clone, PartialEq)]
317pub struct PropertyList {
318 properties: Vec<Property>,
319}
320
321impl PropertyList {
322 pub fn properties(&self) -> &[Property] {
323 &self.properties
324 }
325
326 pub fn into_builder(self) -> PropertyListBuilder {
327 PropertyListBuilder::new().with_properties(self.properties)
328 }
329}
330
331#[derive(Default, Clone)]
333pub struct PropertyListBuilder {
334 properties: Option<Vec<Property>>,
335}
336
337impl PropertyListBuilder {
338 pub fn new() -> Self {
339 PropertyListBuilder::default()
340 }
341 pub fn with_properties(mut self, value: Vec<Property>) -> Self {
342 self.properties = Some(value);
343 self
344 }
345 pub fn build(self) -> Result<PropertyList, BuilderError> {
346 let properties = self
347 .properties
348 .ok_or_else(|| BuilderError::MissingField("properties".into()))?;
349 Ok(PropertyList { properties })
350 }
351}
352
353impl FromProto<track_and_trace_state::PropertyList> for PropertyList {
354 fn from_proto(
355 proto: track_and_trace_state::PropertyList,
356 ) -> Result<Self, ProtoConversionError> {
357 Ok(PropertyList {
358 properties: proto
359 .get_entries()
360 .iter()
361 .cloned()
362 .map(Property::from_proto)
363 .collect::<Result<Vec<Property>, ProtoConversionError>>()?,
364 })
365 }
366}
367
368impl FromNative<PropertyList> for track_and_trace_state::PropertyList {
369 fn from_native(native: PropertyList) -> Result<Self, ProtoConversionError> {
370 let mut proto = track_and_trace_state::PropertyList::new();
371 proto.set_entries(RepeatedField::from_vec(
372 native
373 .properties()
374 .iter()
375 .cloned()
376 .map(Property::into_proto)
377 .collect::<Result<Vec<track_and_trace_state::Property>, ProtoConversionError>>()?,
378 ));
379
380 Ok(proto)
381 }
382}
383
384impl FromBytes<PropertyList> for PropertyList {
385 fn from_bytes(bytes: &[u8]) -> Result<PropertyList, ProtoConversionError> {
386 let proto: track_and_trace_state::PropertyList =
387 Message::parse_from_bytes(bytes).map_err(|_| {
388 ProtoConversionError::SerializationError(
389 "Unable to get PropertyList from Bytes".into(),
390 )
391 })?;
392 proto.into_native()
393 }
394}
395impl IntoBytes for PropertyList {
396 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
397 let proto = self.into_proto()?;
398 let bytes = proto.write_to_bytes().map_err(|_| {
399 ProtoConversionError::SerializationError("Unable to get PropertyList from Bytes".into())
400 })?;
401 Ok(bytes)
402 }
403}
404impl IntoProto<track_and_trace_state::PropertyList> for PropertyList {}
405impl IntoNative<PropertyList> for track_and_trace_state::PropertyList {}
406
407#[derive(Debug, Clone, PartialEq)]
411pub struct ReportedValue {
412 reporter_index: u32,
413 timestamp: u64,
414 value: PropertyValue,
415}
416
417impl ReportedValue {
418 pub fn reporter_index(&self) -> &u32 {
419 &self.reporter_index
420 }
421 pub fn timestamp(&self) -> &u64 {
422 &self.timestamp
423 }
424 pub fn value(&self) -> &PropertyValue {
425 &self.value
426 }
427 pub fn into_builder(self) -> ReportedValueBuilder {
428 ReportedValueBuilder::new()
429 .with_reporter_index(self.reporter_index)
430 .with_timestamp(self.timestamp)
431 .with_value(self.value)
432 }
433}
434
435#[derive(Default, Debug)]
437pub struct ReportedValueBuilder {
438 reporter_index: Option<u32>,
439 timestamp: Option<u64>,
440 value: Option<PropertyValue>,
441}
442
443impl ReportedValueBuilder {
444 pub fn new() -> Self {
445 ReportedValueBuilder::default()
446 }
447 pub fn with_reporter_index(mut self, value: u32) -> Self {
448 self.reporter_index = Some(value);
449 self
450 }
451 pub fn with_timestamp(mut self, value: u64) -> Self {
452 self.timestamp = Some(value);
453 self
454 }
455 pub fn with_value(mut self, value: PropertyValue) -> Self {
456 self.value = Some(value);
457 self
458 }
459 pub fn build(self) -> Result<ReportedValue, BuilderError> {
460 let reporter_index = self
461 .reporter_index
462 .ok_or_else(|| BuilderError::MissingField("reporter_index".into()))?;
463 let timestamp = self
464 .timestamp
465 .ok_or_else(|| BuilderError::MissingField("timestamp".into()))?;
466 let value = self
467 .value
468 .ok_or_else(|| BuilderError::MissingField("value".into()))?;
469 Ok(ReportedValue {
470 reporter_index,
471 timestamp,
472 value,
473 })
474 }
475}
476
477impl FromProto<track_and_trace_state::PropertyPage_ReportedValue> for ReportedValue {
478 fn from_proto(
479 proto: track_and_trace_state::PropertyPage_ReportedValue,
480 ) -> Result<Self, ProtoConversionError> {
481 Ok(ReportedValue {
482 reporter_index: proto.get_reporter_index(),
483 timestamp: proto.get_timestamp(),
484 value: PropertyValue::from_proto(proto.get_value().clone())?,
485 })
486 }
487}
488
489impl FromNative<ReportedValue> for track_and_trace_state::PropertyPage_ReportedValue {
490 fn from_native(native: ReportedValue) -> Result<Self, ProtoConversionError> {
491 let mut proto = track_and_trace_state::PropertyPage_ReportedValue::new();
492 proto.set_reporter_index(*native.reporter_index());
493 proto.set_timestamp(*native.timestamp());
494 proto.set_value(native.value().clone().into_proto()?);
495
496 Ok(proto)
497 }
498}
499
500impl FromBytes<ReportedValue> for ReportedValue {
501 fn from_bytes(bytes: &[u8]) -> Result<ReportedValue, ProtoConversionError> {
502 let proto: track_and_trace_state::PropertyPage_ReportedValue =
503 Message::parse_from_bytes(bytes).map_err(|_| {
504 ProtoConversionError::SerializationError(
505 "Unable to get ReportedValue from bytes".into(),
506 )
507 })?;
508 proto.into_native()
509 }
510}
511impl IntoBytes for ReportedValue {
512 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
513 let proto = self.into_proto()?;
514 let bytes = proto.write_to_bytes().map_err(|_| {
515 ProtoConversionError::SerializationError(
516 "Unable to get ReportedValue from bytes".into(),
517 )
518 })?;
519 Ok(bytes)
520 }
521}
522impl IntoProto<track_and_trace_state::PropertyPage_ReportedValue> for ReportedValue {}
523impl IntoNative<ReportedValue> for track_and_trace_state::PropertyPage_ReportedValue {}
524
525#[derive(Debug, Clone, PartialEq)]
531pub struct PropertyPage {
532 name: String,
533 record_id: String,
534 reported_values: Vec<ReportedValue>,
535}
536
537impl PropertyPage {
538 pub fn name(&self) -> &str {
539 &self.name
540 }
541 pub fn record_id(&self) -> &str {
542 &self.record_id
543 }
544 pub fn reported_values(&self) -> &[ReportedValue] {
545 &self.reported_values
546 }
547
548 pub fn into_builder(self) -> PropertyPageBuilder {
549 PropertyPageBuilder::new()
550 .with_name(self.name)
551 .with_record_id(self.record_id)
552 .with_reported_values(self.reported_values)
553 }
554}
555
556#[derive(Default, Debug)]
558pub struct PropertyPageBuilder {
559 name: Option<String>,
560 record_id: Option<String>,
561 reported_values: Option<Vec<ReportedValue>>,
562}
563
564impl PropertyPageBuilder {
565 pub fn new() -> Self {
566 PropertyPageBuilder::default()
567 }
568 pub fn with_name(mut self, value: String) -> Self {
569 self.name = Some(value);
570 self
571 }
572 pub fn with_record_id(mut self, value: String) -> Self {
573 self.record_id = Some(value);
574 self
575 }
576 pub fn with_reported_values(mut self, value: Vec<ReportedValue>) -> Self {
577 self.reported_values = Some(value);
578 self
579 }
580 pub fn build(self) -> Result<PropertyPage, BuilderError> {
581 let name = self
582 .name
583 .ok_or_else(|| BuilderError::MissingField("name".into()))?;
584 let record_id = self
585 .record_id
586 .ok_or_else(|| BuilderError::MissingField("record_id".into()))?;
587 let reported_values = self
588 .reported_values
589 .ok_or_else(|| BuilderError::MissingField("reported_values".into()))?;
590 Ok(PropertyPage {
591 name,
592 record_id,
593 reported_values,
594 })
595 }
596}
597
598impl FromProto<track_and_trace_state::PropertyPage> for PropertyPage {
599 fn from_proto(
600 proto: track_and_trace_state::PropertyPage,
601 ) -> Result<Self, ProtoConversionError> {
602 Ok(PropertyPage {
603 name: proto.get_name().to_string(),
604 record_id: proto.get_record_id().to_string(),
605 reported_values: proto
606 .get_reported_values()
607 .iter()
608 .cloned()
609 .map(ReportedValue::from_proto)
610 .collect::<Result<Vec<ReportedValue>, ProtoConversionError>>()?,
611 })
612 }
613}
614
615impl FromNative<PropertyPage> for track_and_trace_state::PropertyPage {
616 fn from_native(native: PropertyPage) -> Result<Self, ProtoConversionError> {
617 let mut proto = track_and_trace_state::PropertyPage::new();
618 proto.set_name(native.name().to_string());
619 proto.set_record_id(native.record_id().to_string());
620 proto.set_reported_values(RepeatedField::from_vec(
621 native
622 .reported_values()
623 .iter()
624 .cloned()
625 .map(ReportedValue::into_proto)
626 .collect::<Result<
627 Vec<track_and_trace_state::PropertyPage_ReportedValue>,
628 ProtoConversionError,
629 >>()?,
630 ));
631
632 Ok(proto)
633 }
634}
635
636impl FromBytes<PropertyPage> for PropertyPage {
637 fn from_bytes(bytes: &[u8]) -> Result<PropertyPage, ProtoConversionError> {
638 let proto: track_and_trace_state::PropertyPage =
639 Message::parse_from_bytes(bytes).map_err(|_| {
640 ProtoConversionError::SerializationError(
641 "Undable to get PropertyPage from bytes".into(),
642 )
643 })?;
644 proto.into_native()
645 }
646}
647impl IntoBytes for PropertyPage {
648 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
649 let proto = self.into_proto()?;
650 let bytes = proto.write_to_bytes().map_err(|_| {
651 ProtoConversionError::SerializationError(
652 "Undable to get PropertyPage from bytes".into(),
653 )
654 })?;
655 Ok(bytes)
656 }
657}
658impl IntoProto<track_and_trace_state::PropertyPage> for PropertyPage {}
659impl IntoNative<PropertyPage> for track_and_trace_state::PropertyPage {}
660
661#[derive(Debug, Clone, PartialEq)]
663pub struct PropertyPageList {
664 property_pages: Vec<PropertyPage>,
665}
666
667impl PropertyPageList {
668 pub fn property_pages(&self) -> &[PropertyPage] {
669 &self.property_pages
670 }
671
672 pub fn into_builder(self) -> PropertyPageListBuilder {
673 PropertyPageListBuilder::new().with_property_pages(self.property_pages)
674 }
675}
676
677#[derive(Default, Debug)]
679pub struct PropertyPageListBuilder {
680 property_pages: Option<Vec<PropertyPage>>,
681}
682
683impl PropertyPageListBuilder {
684 pub fn new() -> Self {
685 PropertyPageListBuilder::default()
686 }
687 pub fn with_property_pages(mut self, value: Vec<PropertyPage>) -> Self {
688 self.property_pages = Some(value);
689 self
690 }
691 pub fn build(self) -> Result<PropertyPageList, BuilderError> {
692 let property_pages = self
693 .property_pages
694 .ok_or_else(|| BuilderError::MissingField("property_pages".into()))?;
695 Ok(PropertyPageList { property_pages })
696 }
697}
698
699impl FromProto<track_and_trace_state::PropertyPageList> for PropertyPageList {
700 fn from_proto(
701 proto: track_and_trace_state::PropertyPageList,
702 ) -> Result<Self, ProtoConversionError> {
703 Ok(PropertyPageList {
704 property_pages: proto
705 .get_entries()
706 .iter()
707 .cloned()
708 .map(PropertyPage::from_proto)
709 .collect::<Result<Vec<PropertyPage>, ProtoConversionError>>()?,
710 })
711 }
712}
713
714impl FromNative<PropertyPageList> for track_and_trace_state::PropertyPageList {
715 fn from_native(native: PropertyPageList) -> Result<Self, ProtoConversionError> {
716 let mut proto = track_and_trace_state::PropertyPageList::new();
717 proto.set_entries(RepeatedField::from_vec(
718 native
719 .property_pages()
720 .iter()
721 .cloned()
722 .map(PropertyPage::into_proto)
723 .collect::<Result<Vec<track_and_trace_state::PropertyPage>, ProtoConversionError>>(
724 )?,
725 ));
726
727 Ok(proto)
728 }
729}
730
731impl FromBytes<PropertyPageList> for PropertyPageList {
732 fn from_bytes(bytes: &[u8]) -> Result<PropertyPageList, ProtoConversionError> {
733 let proto: track_and_trace_state::PropertyPageList = Message::parse_from_bytes(bytes)
734 .map_err(|_| {
735 ProtoConversionError::SerializationError(
736 "Unable to get PropertyPageList from Bytes".into(),
737 )
738 })?;
739 proto.into_native()
740 }
741}
742impl IntoBytes for PropertyPageList {
743 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
744 let proto = self.into_proto()?;
745 let bytes = proto.write_to_bytes().map_err(|_| {
746 ProtoConversionError::SerializationError(
747 "Unable to get PropertyPageList from Bytes".into(),
748 )
749 })?;
750 Ok(bytes)
751 }
752}
753impl IntoProto<track_and_trace_state::PropertyPageList> for PropertyPageList {}
754impl IntoNative<PropertyPageList> for track_and_trace_state::PropertyPageList {}
755
756#[derive(Debug, Clone, PartialEq)]
758pub enum Role {
759 Owner,
760 Custodian,
761 Reporter,
762}
763
764impl Default for Role {
765 fn default() -> Role {
766 Role::Owner
767 }
768}
769
770impl FromProto<track_and_trace_state::Proposal_Role> for Role {
771 fn from_proto(
772 roles: track_and_trace_state::Proposal_Role,
773 ) -> Result<Self, ProtoConversionError> {
774 match roles {
775 track_and_trace_state::Proposal_Role::OWNER => Ok(Role::Owner),
776 track_and_trace_state::Proposal_Role::CUSTODIAN => Ok(Role::Custodian),
777 track_and_trace_state::Proposal_Role::REPORTER => Ok(Role::Reporter),
778 }
779 }
780}
781
782impl FromNative<Role> for track_and_trace_state::Proposal_Role {
783 fn from_native(roles: Role) -> Result<Self, ProtoConversionError> {
784 match roles {
785 Role::Owner => Ok(track_and_trace_state::Proposal_Role::OWNER),
786 Role::Custodian => Ok(track_and_trace_state::Proposal_Role::CUSTODIAN),
787 Role::Reporter => Ok(track_and_trace_state::Proposal_Role::REPORTER),
788 }
789 }
790}
791
792impl IntoProto<track_and_trace_state::Proposal_Role> for Role {}
793impl IntoNative<Role> for track_and_trace_state::Proposal_Role {}
794
795#[derive(Debug, Clone, PartialEq)]
797pub enum Status {
798 Open,
799 Accepted,
800 Rejected,
801 Canceled,
802}
803
804impl Default for Status {
805 fn default() -> Status {
806 Status::Open
807 }
808}
809
810impl FromProto<track_and_trace_state::Proposal_Status> for Status {
811 fn from_proto(
812 statuses: track_and_trace_state::Proposal_Status,
813 ) -> Result<Self, ProtoConversionError> {
814 match statuses {
815 track_and_trace_state::Proposal_Status::OPEN => Ok(Status::Open),
816 track_and_trace_state::Proposal_Status::ACCEPTED => Ok(Status::Accepted),
817 track_and_trace_state::Proposal_Status::REJECTED => Ok(Status::Rejected),
818 track_and_trace_state::Proposal_Status::CANCELED => Ok(Status::Canceled),
819 }
820 }
821}
822
823impl FromNative<Status> for track_and_trace_state::Proposal_Status {
824 fn from_native(statuses: Status) -> Result<Self, ProtoConversionError> {
825 match statuses {
826 Status::Open => Ok(track_and_trace_state::Proposal_Status::OPEN),
827 Status::Accepted => Ok(track_and_trace_state::Proposal_Status::ACCEPTED),
828 Status::Rejected => Ok(track_and_trace_state::Proposal_Status::REJECTED),
829 Status::Canceled => Ok(track_and_trace_state::Proposal_Status::CANCELED),
830 }
831 }
832}
833
834impl IntoProto<track_and_trace_state::Proposal_Status> for Status {}
835impl IntoNative<Status> for track_and_trace_state::Proposal_Status {}
836
837#[derive(Debug, Clone, PartialEq)]
842pub struct Proposal {
843 record_id: String,
844 timestamp: u64,
845 issuing_agent: String,
846 receiving_agent: String,
847 role: Role,
848 properties: Vec<String>,
849 status: Status,
850 terms: String,
851}
852
853impl Proposal {
854 pub fn record_id(&self) -> &str {
855 &self.record_id
856 }
857 pub fn timestamp(&self) -> &u64 {
858 &self.timestamp
859 }
860 pub fn issuing_agent(&self) -> &str {
861 &self.issuing_agent
862 }
863 pub fn receiving_agent(&self) -> &str {
864 &self.receiving_agent
865 }
866 pub fn role(&self) -> &Role {
867 &self.role
868 }
869 pub fn properties(&self) -> &[String] {
870 &self.properties
871 }
872 pub fn status(&self) -> &Status {
873 &self.status
874 }
875 pub fn terms(&self) -> &str {
876 &self.terms
877 }
878 pub fn into_builder(self) -> ProposalBuilder {
879 ProposalBuilder::new()
880 .with_record_id(self.record_id)
881 .with_timestamp(self.timestamp)
882 .with_issuing_agent(self.issuing_agent)
883 .with_receiving_agent(self.receiving_agent)
884 .with_role(self.role)
885 .with_properties(self.properties)
886 .with_status(self.status)
887 .with_terms(self.terms)
888 }
889}
890
891#[derive(Default, Debug)]
893pub struct ProposalBuilder {
894 record_id: Option<String>,
895 timestamp: Option<u64>,
896 issuing_agent: Option<String>,
897 receiving_agent: Option<String>,
898 role: Option<Role>,
899 properties: Option<Vec<String>>,
900 status: Option<Status>,
901 terms: Option<String>,
902}
903
904impl ProposalBuilder {
905 pub fn new() -> Self {
906 ProposalBuilder::default()
907 }
908 pub fn with_record_id(mut self, value: String) -> Self {
909 self.record_id = Some(value);
910 self
911 }
912 pub fn with_timestamp(mut self, value: u64) -> Self {
913 self.timestamp = Some(value);
914 self
915 }
916 pub fn with_issuing_agent(mut self, value: String) -> Self {
917 self.issuing_agent = Some(value);
918 self
919 }
920 pub fn with_receiving_agent(mut self, value: String) -> Self {
921 self.receiving_agent = Some(value);
922 self
923 }
924 pub fn with_role(mut self, value: Role) -> Self {
925 self.role = Some(value);
926 self
927 }
928 pub fn with_properties(mut self, value: Vec<String>) -> Self {
929 self.properties = Some(value);
930 self
931 }
932 pub fn with_status(mut self, value: Status) -> Self {
933 self.status = Some(value);
934 self
935 }
936 pub fn with_terms(mut self, value: String) -> Self {
937 self.terms = Some(value);
938 self
939 }
940 pub fn build(self) -> Result<Proposal, BuilderError> {
941 let record_id = self
942 .record_id
943 .ok_or_else(|| BuilderError::MissingField("record_id".into()))?;
944 let timestamp = self
945 .timestamp
946 .ok_or_else(|| BuilderError::MissingField("timestamp".into()))?;
947 let issuing_agent = self
948 .issuing_agent
949 .ok_or_else(|| BuilderError::MissingField("issuing_agent".into()))?;
950 let receiving_agent = self
951 .receiving_agent
952 .ok_or_else(|| BuilderError::MissingField("receiving_agent".into()))?;
953 let role = self
954 .role
955 .ok_or_else(|| BuilderError::MissingField("role".into()))?;
956 let properties = self
957 .properties
958 .ok_or_else(|| BuilderError::MissingField("properties".into()))?;
959 let status = self
960 .status
961 .ok_or_else(|| BuilderError::MissingField("status".into()))?;
962 let terms = self
963 .terms
964 .ok_or_else(|| BuilderError::MissingField("terms".into()))?;
965 Ok(Proposal {
966 record_id,
967 timestamp,
968 issuing_agent,
969 receiving_agent,
970 role,
971 properties,
972 status,
973 terms,
974 })
975 }
976}
977
978impl FromProto<track_and_trace_state::Proposal> for Proposal {
979 fn from_proto(proto: track_and_trace_state::Proposal) -> Result<Self, ProtoConversionError> {
980 Ok(Proposal {
981 record_id: proto.get_record_id().to_string(),
982 timestamp: proto.get_timestamp(),
983 issuing_agent: proto.get_issuing_agent().to_string(),
984 receiving_agent: proto.get_receiving_agent().to_string(),
985 role: Role::from_proto(proto.get_role())?,
986 properties: proto
987 .get_properties()
988 .iter()
989 .cloned()
990 .map(String::from)
991 .collect(),
992 status: Status::from_proto(proto.get_status())?,
993 terms: proto.get_terms().to_string(),
994 })
995 }
996}
997
998impl FromNative<Proposal> for track_and_trace_state::Proposal {
999 fn from_native(native: Proposal) -> Result<Self, ProtoConversionError> {
1000 let mut proto = track_and_trace_state::Proposal::new();
1001
1002 proto.set_record_id(native.record_id().to_string());
1003 proto.set_timestamp(*native.timestamp());
1004 proto.set_issuing_agent(native.issuing_agent().to_string());
1005 proto.set_receiving_agent(native.receiving_agent().to_string());
1006 proto.set_role(native.role().clone().into_proto()?);
1007 proto.set_properties(RepeatedField::from_vec(native.properties().to_vec()));
1008 proto.set_status(native.status().clone().into_proto()?);
1009 proto.set_terms(native.terms().to_string());
1010
1011 Ok(proto)
1012 }
1013}
1014
1015impl FromBytes<Proposal> for Proposal {
1016 fn from_bytes(bytes: &[u8]) -> Result<Proposal, ProtoConversionError> {
1017 let proto: track_and_trace_state::Proposal =
1018 Message::parse_from_bytes(bytes).map_err(|_| {
1019 ProtoConversionError::SerializationError("Unable to get Proposal from bytes".into())
1020 })?;
1021 proto.into_native()
1022 }
1023}
1024
1025impl IntoBytes for Proposal {
1026 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1027 let proto = self.into_proto()?;
1028 let bytes = proto.write_to_bytes().map_err(|_| {
1029 ProtoConversionError::SerializationError("Unable to get Proposal from bytes".into())
1030 })?;
1031 Ok(bytes)
1032 }
1033}
1034impl IntoProto<track_and_trace_state::Proposal> for Proposal {}
1035impl IntoNative<Proposal> for track_and_trace_state::Proposal {}
1036
1037#[derive(Debug, Clone, PartialEq)]
1039pub struct ProposalList {
1040 proposals: Vec<Proposal>,
1041}
1042
1043impl ProposalList {
1044 pub fn proposals(&self) -> &[Proposal] {
1045 &self.proposals
1046 }
1047
1048 pub fn into_builder(self) -> ProposalListBuilder {
1049 ProposalListBuilder::new().with_proposals(self.proposals)
1050 }
1051}
1052
1053#[derive(Default, Debug)]
1055pub struct ProposalListBuilder {
1056 proposals: Option<Vec<Proposal>>,
1057}
1058
1059impl ProposalListBuilder {
1060 pub fn new() -> Self {
1061 ProposalListBuilder::default()
1062 }
1063 pub fn with_proposals(mut self, value: Vec<Proposal>) -> Self {
1064 self.proposals = Some(value);
1065 self
1066 }
1067 pub fn build(self) -> Result<ProposalList, BuilderError> {
1068 let proposals = self
1069 .proposals
1070 .ok_or_else(|| BuilderError::MissingField("proposals".into()))?;
1071 Ok(ProposalList { proposals })
1072 }
1073}
1074
1075impl FromProto<track_and_trace_state::ProposalList> for ProposalList {
1076 fn from_proto(
1077 proto: track_and_trace_state::ProposalList,
1078 ) -> Result<Self, ProtoConversionError> {
1079 Ok(ProposalList {
1080 proposals: proto
1081 .get_entries()
1082 .iter()
1083 .cloned()
1084 .map(Proposal::from_proto)
1085 .collect::<Result<Vec<Proposal>, ProtoConversionError>>()?,
1086 })
1087 }
1088}
1089
1090impl FromNative<ProposalList> for track_and_trace_state::ProposalList {
1091 fn from_native(native: ProposalList) -> Result<Self, ProtoConversionError> {
1092 let mut proto = track_and_trace_state::ProposalList::new();
1093 proto.set_entries(RepeatedField::from_vec(
1094 native
1095 .proposals()
1096 .iter()
1097 .cloned()
1098 .map(Proposal::into_proto)
1099 .collect::<Result<Vec<track_and_trace_state::Proposal>, ProtoConversionError>>()?,
1100 ));
1101
1102 Ok(proto)
1103 }
1104}
1105
1106impl FromBytes<ProposalList> for ProposalList {
1107 fn from_bytes(bytes: &[u8]) -> Result<ProposalList, ProtoConversionError> {
1108 let proto: track_and_trace_state::ProposalList =
1109 Message::parse_from_bytes(bytes).map_err(|_| {
1110 ProtoConversionError::SerializationError(
1111 "Unable to get ProposalList from bytes".into(),
1112 )
1113 })?;
1114 proto.into_native()
1115 }
1116}
1117
1118impl IntoBytes for ProposalList {
1119 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1120 let proto = self.into_proto()?;
1121 let bytes = proto.write_to_bytes().map_err(|_| {
1122 ProtoConversionError::SerializationError("Unable to get ProposalList from bytes".into())
1123 })?;
1124 Ok(bytes)
1125 }
1126}
1127
1128impl IntoProto<track_and_trace_state::ProposalList> for ProposalList {}
1129impl IntoNative<ProposalList> for track_and_trace_state::ProposalList {}
1130
1131#[derive(Debug, Clone, PartialEq)]
1136pub struct AssociatedAgent {
1137 agent_id: String,
1138 timestamp: u64,
1139}
1140
1141impl AssociatedAgent {
1142 pub fn agent_id(&self) -> &str {
1143 &self.agent_id
1144 }
1145 pub fn timestamp(&self) -> &u64 {
1146 &self.timestamp
1147 }
1148
1149 pub fn into_builder(self) -> AssociatedAgentBuilder {
1150 AssociatedAgentBuilder::new()
1151 .with_agent_id(self.agent_id)
1152 .with_timestamp(self.timestamp)
1153 }
1154}
1155
1156#[derive(Default, Debug)]
1158pub struct AssociatedAgentBuilder {
1159 agent_id: Option<String>,
1160 timestamp: Option<u64>,
1161}
1162
1163impl AssociatedAgentBuilder {
1164 pub fn new() -> Self {
1165 AssociatedAgentBuilder::default()
1166 }
1167 pub fn with_agent_id(mut self, value: String) -> Self {
1168 self.agent_id = Some(value);
1169 self
1170 }
1171 pub fn with_timestamp(mut self, value: u64) -> Self {
1172 self.timestamp = Some(value);
1173 self
1174 }
1175 pub fn build(self) -> Result<AssociatedAgent, BuilderError> {
1176 let agent_id = self
1177 .agent_id
1178 .ok_or_else(|| BuilderError::MissingField("agent_id".into()))?;
1179 let timestamp = self
1180 .timestamp
1181 .ok_or_else(|| BuilderError::MissingField("timestamp".into()))?;
1182 Ok(AssociatedAgent {
1183 agent_id,
1184 timestamp,
1185 })
1186 }
1187}
1188
1189impl FromProto<track_and_trace_state::Record_AssociatedAgent> for AssociatedAgent {
1190 fn from_proto(
1191 proto: track_and_trace_state::Record_AssociatedAgent,
1192 ) -> Result<Self, ProtoConversionError> {
1193 Ok(AssociatedAgent {
1194 agent_id: proto.get_agent_id().to_string(),
1195 timestamp: proto.get_timestamp(),
1196 })
1197 }
1198}
1199
1200impl FromNative<AssociatedAgent> for track_and_trace_state::Record_AssociatedAgent {
1201 fn from_native(native: AssociatedAgent) -> Result<Self, ProtoConversionError> {
1202 let mut proto = track_and_trace_state::Record_AssociatedAgent::new();
1203
1204 proto.set_agent_id(native.agent_id().to_string());
1205 proto.set_timestamp(*native.timestamp());
1206
1207 Ok(proto)
1208 }
1209}
1210
1211impl FromBytes<AssociatedAgent> for AssociatedAgent {
1212 fn from_bytes(bytes: &[u8]) -> Result<AssociatedAgent, ProtoConversionError> {
1213 let proto: track_and_trace_state::Record_AssociatedAgent = Message::parse_from_bytes(bytes)
1214 .map_err(|_| {
1215 ProtoConversionError::SerializationError(
1216 "Unable to get AssociatedAgent from bytes".into(),
1217 )
1218 })?;
1219 proto.into_native()
1220 }
1221}
1222impl IntoBytes for AssociatedAgent {
1223 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1224 let proto = self.into_proto()?;
1225 let bytes = proto.write_to_bytes().map_err(|_| {
1226 ProtoConversionError::SerializationError(
1227 "Unable to get AssociatedAgent from bytes".into(),
1228 )
1229 })?;
1230 Ok(bytes)
1231 }
1232}
1233impl IntoProto<track_and_trace_state::Record_AssociatedAgent> for AssociatedAgent {}
1234impl IntoNative<AssociatedAgent> for track_and_trace_state::Record_AssociatedAgent {}
1235
1236#[derive(Debug, Clone, PartialEq)]
1240pub struct Record {
1241 record_id: String,
1242 schema: String,
1243 owners: Vec<AssociatedAgent>,
1244 custodians: Vec<AssociatedAgent>,
1245 field_final: bool,
1246}
1247
1248impl Record {
1249 pub fn record_id(&self) -> &str {
1250 &self.record_id
1251 }
1252 pub fn schema(&self) -> &str {
1253 &self.schema
1254 }
1255 pub fn owners(&self) -> &[AssociatedAgent] {
1256 &self.owners
1257 }
1258 pub fn custodians(&self) -> &[AssociatedAgent] {
1259 &self.custodians
1260 }
1261 pub fn field_final(&self) -> &bool {
1262 &self.field_final
1263 }
1264 pub fn into_builder(self) -> RecordBuilder {
1265 RecordBuilder::new()
1266 .with_record_id(self.record_id)
1267 .with_schema(self.schema)
1268 .with_owners(self.owners)
1269 .with_custodians(self.custodians)
1270 .with_field_final(self.field_final)
1271 }
1272}
1273
1274#[derive(Default, Debug)]
1276pub struct RecordBuilder {
1277 record_id: Option<String>,
1278 schema: Option<String>,
1279 owners: Option<Vec<AssociatedAgent>>,
1280 custodians: Option<Vec<AssociatedAgent>>,
1281 field_final: Option<bool>,
1282}
1283
1284impl RecordBuilder {
1285 pub fn new() -> Self {
1286 RecordBuilder::default()
1287 }
1288 pub fn with_record_id(mut self, value: String) -> Self {
1289 self.record_id = Some(value);
1290 self
1291 }
1292 pub fn with_schema(mut self, value: String) -> Self {
1293 self.schema = Some(value);
1294 self
1295 }
1296 pub fn with_owners(mut self, value: Vec<AssociatedAgent>) -> Self {
1297 self.owners = Some(value);
1298 self
1299 }
1300 pub fn with_custodians(mut self, value: Vec<AssociatedAgent>) -> Self {
1301 self.custodians = Some(value);
1302 self
1303 }
1304 pub fn with_field_final(mut self, value: bool) -> Self {
1305 self.field_final = Some(value);
1306 self
1307 }
1308 pub fn build(self) -> Result<Record, BuilderError> {
1309 let record_id = self
1310 .record_id
1311 .ok_or_else(|| BuilderError::MissingField("record_id".into()))?;
1312 let schema = self
1313 .schema
1314 .ok_or_else(|| BuilderError::MissingField("schema".into()))?;
1315 let owners = self
1316 .owners
1317 .ok_or_else(|| BuilderError::MissingField("owners".into()))?;
1318 let custodians = self
1319 .custodians
1320 .ok_or_else(|| BuilderError::MissingField("custodians".into()))?;
1321 let field_final = self
1322 .field_final
1323 .ok_or_else(|| BuilderError::MissingField("field_final".into()))?;
1324 Ok(Record {
1325 record_id,
1326 schema,
1327 owners,
1328 custodians,
1329 field_final,
1330 })
1331 }
1332}
1333
1334impl FromProto<track_and_trace_state::Record> for Record {
1335 fn from_proto(proto: track_and_trace_state::Record) -> Result<Self, ProtoConversionError> {
1336 Ok(Record {
1337 record_id: proto.get_record_id().to_string(),
1338 schema: proto.get_schema().to_string(),
1339 owners: proto
1340 .get_owners()
1341 .iter()
1342 .cloned()
1343 .map(AssociatedAgent::from_proto)
1344 .collect::<Result<Vec<AssociatedAgent>, ProtoConversionError>>()?,
1345 custodians: proto
1346 .get_custodians()
1347 .iter()
1348 .cloned()
1349 .map(AssociatedAgent::from_proto)
1350 .collect::<Result<Vec<AssociatedAgent>, ProtoConversionError>>()?,
1351 field_final: proto.get_field_final(),
1352 })
1353 }
1354}
1355
1356impl FromNative<Record> for track_and_trace_state::Record {
1357 fn from_native(native: Record) -> Result<Self, ProtoConversionError> {
1358 let mut proto = track_and_trace_state::Record::new();
1359 proto.set_record_id(native.record_id().to_string());
1360 proto.set_schema(native.schema().to_string());
1361 proto.set_owners(
1362 RepeatedField::from_vec(
1363 native
1364 .owners()
1365 .iter()
1366 .cloned()
1367 .map(AssociatedAgent::into_proto)
1368 .collect::<Result<
1369 Vec<track_and_trace_state::Record_AssociatedAgent>,
1370 ProtoConversionError,
1371 >>()?,
1372 ),
1373 );
1374 proto.set_custodians(
1375 RepeatedField::from_vec(
1376 native
1377 .custodians()
1378 .iter()
1379 .cloned()
1380 .map(AssociatedAgent::into_proto)
1381 .collect::<Result<
1382 Vec<track_and_trace_state::Record_AssociatedAgent>,
1383 ProtoConversionError,
1384 >>()?,
1385 ),
1386 );
1387 proto.set_field_final(*native.field_final());
1388
1389 Ok(proto)
1390 }
1391}
1392
1393impl FromBytes<Record> for Record {
1394 fn from_bytes(bytes: &[u8]) -> Result<Record, ProtoConversionError> {
1395 let proto: track_and_trace_state::Record =
1396 Message::parse_from_bytes(bytes).map_err(|_| {
1397 ProtoConversionError::SerializationError("Unable to get Record from bytes".into())
1398 })?;
1399 proto.into_native()
1400 }
1401}
1402impl IntoBytes for Record {
1403 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1404 let proto = self.into_proto()?;
1405 let bytes = proto.write_to_bytes().map_err(|_| {
1406 ProtoConversionError::SerializationError("Unable to get Record from bytes".into())
1407 })?;
1408 Ok(bytes)
1409 }
1410}
1411impl IntoProto<track_and_trace_state::Record> for Record {}
1412impl IntoNative<Record> for track_and_trace_state::Record {}
1413
1414#[derive(Debug, Clone, PartialEq)]
1416pub struct RecordList {
1417 records: Vec<Record>,
1418}
1419
1420impl RecordList {
1421 pub fn records(&self) -> &[Record] {
1422 &self.records
1423 }
1424
1425 pub fn into_builder(self) -> RecordListBuilder {
1426 RecordListBuilder::new().with_records(self.records)
1427 }
1428}
1429
1430#[derive(Default, Debug)]
1432pub struct RecordListBuilder {
1433 records: Option<Vec<Record>>,
1434}
1435
1436impl RecordListBuilder {
1437 pub fn new() -> Self {
1438 RecordListBuilder::default()
1439 }
1440 pub fn with_records(mut self, value: Vec<Record>) -> Self {
1441 self.records = Some(value);
1442 self
1443 }
1444 pub fn build(self) -> Result<RecordList, BuilderError> {
1445 let records = self
1446 .records
1447 .ok_or_else(|| BuilderError::MissingField("records".into()))?;
1448 Ok(RecordList { records })
1449 }
1450}
1451
1452impl FromProto<track_and_trace_state::RecordList> for RecordList {
1453 fn from_proto(proto: track_and_trace_state::RecordList) -> Result<Self, ProtoConversionError> {
1454 Ok(RecordList {
1455 records: proto
1456 .get_entries()
1457 .iter()
1458 .cloned()
1459 .map(Record::from_proto)
1460 .collect::<Result<Vec<Record>, ProtoConversionError>>()?,
1461 })
1462 }
1463}
1464
1465impl FromNative<RecordList> for track_and_trace_state::RecordList {
1466 fn from_native(native: RecordList) -> Result<Self, ProtoConversionError> {
1467 let mut proto = track_and_trace_state::RecordList::new();
1468 proto.set_entries(RepeatedField::from_vec(
1469 native
1470 .records()
1471 .iter()
1472 .cloned()
1473 .map(Record::into_proto)
1474 .collect::<Result<Vec<track_and_trace_state::Record>, ProtoConversionError>>()?,
1475 ));
1476
1477 Ok(proto)
1478 }
1479}
1480
1481impl FromBytes<RecordList> for RecordList {
1482 fn from_bytes(bytes: &[u8]) -> Result<RecordList, ProtoConversionError> {
1483 let proto: track_and_trace_state::RecordList =
1484 Message::parse_from_bytes(bytes).map_err(|_| {
1485 ProtoConversionError::SerializationError("Unable to get Record from bytes".into())
1486 })?;
1487 proto.into_native()
1488 }
1489}
1490
1491impl IntoBytes for RecordList {
1492 fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1493 let proto = self.into_proto()?;
1494 let bytes = proto.write_to_bytes().map_err(|_| {
1495 ProtoConversionError::SerializationError("Unable to get Record from bytes".into())
1496 })?;
1497 Ok(bytes)
1498 }
1499}
1500impl IntoProto<track_and_trace_state::RecordList> for RecordList {}
1501impl IntoNative<RecordList> for track_and_trace_state::RecordList {}
1502
1503#[cfg(test)]
1504mod tests {
1505 use super::*;
1506 use crate::protocol::schema::state::{
1507 DataType, PropertyDefinitionBuilder, PropertyValueBuilder,
1508 };
1509 use std::fmt::Debug;
1510
1511 fn test_from_bytes<T: FromBytes<T> + Clone + PartialEq + IntoBytes + Debug, F>(
1512 under_test: T,
1513 from_bytes: F,
1514 ) where
1515 F: Fn(&[u8]) -> Result<T, ProtoConversionError>,
1516 {
1517 let bytes = under_test.clone().into_bytes().unwrap();
1518 let created_from_bytes = from_bytes(&bytes).unwrap();
1519 assert_eq!(under_test, created_from_bytes);
1520 }
1521
1522 #[test]
1523 fn test_reporter_builder() {
1525 let builder = ReporterBuilder::new();
1526 let reporter = builder
1527 .with_public_key("1234".to_string())
1528 .with_authorized(true)
1529 .with_index(0)
1530 .build()
1531 .unwrap();
1532
1533 assert_eq!(reporter.public_key(), "1234");
1534 assert_eq!(*reporter.authorized(), true);
1535 assert_eq!(*reporter.index(), 0);
1536 }
1537
1538 #[test]
1539 fn test_reporter_into_builder() {
1541 let reporter = ReporterBuilder::new()
1542 .with_public_key("1234".to_string())
1543 .with_authorized(true)
1544 .with_index(0)
1545 .build()
1546 .unwrap();
1547
1548 let builder = reporter.into_builder();
1549
1550 assert_eq!(builder.public_key, Some("1234".to_string()));
1551 assert_eq!(builder.authorized, Some(true));
1552 assert_eq!(builder.index, Some(0));
1553 }
1554
1555 #[test]
1556 fn test_reporter_bytes() {
1559 let builder = ReporterBuilder::new();
1560 let original = builder
1561 .with_public_key("1234".to_string())
1562 .with_authorized(true)
1563 .with_index(0)
1564 .build()
1565 .unwrap();
1566
1567 test_from_bytes(original, Reporter::from_bytes);
1568 }
1569
1570 #[test]
1571 fn test_property_builder() {
1573 let property_definition = PropertyDefinitionBuilder::new()
1574 .with_name("i dunno".into())
1575 .with_data_type(DataType::String)
1576 .with_required(true)
1577 .with_description("test".into())
1578 .build()
1579 .unwrap();
1580
1581 let reporter = ReporterBuilder::new()
1582 .with_public_key("1234".to_string())
1583 .with_authorized(true)
1584 .with_index(0)
1585 .build()
1586 .unwrap();
1587
1588 let property = PropertyBuilder::new()
1589 .with_name("taco".into())
1590 .with_record_id("taco1234".into())
1591 .with_property_definition(property_definition.clone())
1592 .with_reporters(vec![reporter.clone()])
1593 .with_current_page(0)
1594 .with_wrapped(true)
1595 .build()
1596 .unwrap();
1597
1598 assert_eq!(property.name(), "taco");
1599 assert_eq!(property.record_id(), "taco1234");
1600 assert_eq!(*property.property_definition(), property_definition);
1601 assert!(property.reporters().iter().any(|x| *x == reporter));
1602 assert_eq!(*property.current_page(), 0);
1603 assert_eq!(*property.wrapped(), true);
1604 }
1605
1606 #[test]
1607 fn test_property_into_builder() {
1609 let property_definition = PropertyDefinitionBuilder::new()
1610 .with_name("i dunno".into())
1611 .with_data_type(DataType::String)
1612 .with_required(true)
1613 .with_description("test".into())
1614 .build()
1615 .unwrap();
1616
1617 let reporter = ReporterBuilder::new()
1618 .with_public_key("1234".to_string())
1619 .with_authorized(true)
1620 .with_index(0)
1621 .build()
1622 .unwrap();
1623
1624 let property = PropertyBuilder::new()
1625 .with_name("taco".into())
1626 .with_record_id("taco1234".into())
1627 .with_property_definition(property_definition.clone())
1628 .with_reporters(vec![reporter.clone()])
1629 .with_current_page(0)
1630 .with_wrapped(true)
1631 .build()
1632 .unwrap();
1633
1634 let builder = property.into_builder();
1635
1636 assert_eq!(builder.name, Some("taco".to_string()));
1637 assert_eq!(builder.record_id, Some("taco1234".to_string()));
1638 assert_eq!(builder.property_definition, Some(property_definition));
1639 assert_eq!(builder.reporters, Some(vec![reporter]));
1640 assert_eq!(builder.current_page, Some(0));
1641 assert_eq!(builder.wrapped, Some(true));
1642 }
1643
1644 #[test]
1645 fn test_property_bytes() {
1648 let property_definition = PropertyDefinitionBuilder::new()
1649 .with_name("i dunno".into())
1650 .with_data_type(DataType::String)
1651 .with_required(true)
1652 .with_description("test".into())
1653 .build()
1654 .unwrap();
1655
1656 let reporter = ReporterBuilder::new()
1657 .with_public_key("1234".to_string())
1658 .with_authorized(true)
1659 .with_index(0)
1660 .build()
1661 .unwrap();
1662
1663 let property = PropertyBuilder::new()
1664 .with_name("taco".into())
1665 .with_record_id("taco1234".into())
1666 .with_property_definition(property_definition.clone())
1667 .with_reporters(vec![reporter.clone()])
1668 .with_current_page(0)
1669 .with_wrapped(true)
1670 .build()
1671 .unwrap();
1672
1673 test_from_bytes(property, Property::from_bytes);
1674 }
1675
1676 #[test]
1677 fn test_property_list_builder() {
1679 let property_definition = PropertyDefinitionBuilder::new()
1680 .with_name("i dunno".into())
1681 .with_data_type(DataType::String)
1682 .with_required(true)
1683 .with_description("test".into())
1684 .build()
1685 .unwrap();
1686
1687 let reporter = ReporterBuilder::new()
1688 .with_public_key("1234".to_string())
1689 .with_authorized(true)
1690 .with_index(0)
1691 .build()
1692 .unwrap();
1693
1694 let property = PropertyBuilder::new()
1695 .with_name("taco".into())
1696 .with_record_id("taco1234".into())
1697 .with_property_definition(property_definition.clone())
1698 .with_reporters(vec![reporter.clone()])
1699 .with_current_page(0)
1700 .with_wrapped(true)
1701 .build()
1702 .unwrap();
1703
1704 let property_list = PropertyListBuilder::new()
1705 .with_properties(vec![property.clone()])
1706 .build()
1707 .unwrap();
1708
1709 assert!(property_list.properties().iter().any(|x| *x == property));
1710 }
1711
1712 #[test]
1713 fn test_property_list_into_builder() {
1715 let property_definition = PropertyDefinitionBuilder::new()
1716 .with_name("i dunno".into())
1717 .with_data_type(DataType::String)
1718 .with_required(true)
1719 .with_description("test".into())
1720 .build()
1721 .unwrap();
1722
1723 let reporter = ReporterBuilder::new()
1724 .with_public_key("1234".to_string())
1725 .with_authorized(true)
1726 .with_index(0)
1727 .build()
1728 .unwrap();
1729
1730 let property = PropertyBuilder::new()
1731 .with_name("taco".into())
1732 .with_record_id("taco1234".into())
1733 .with_property_definition(property_definition.clone())
1734 .with_reporters(vec![reporter.clone()])
1735 .with_current_page(0)
1736 .with_wrapped(true)
1737 .build()
1738 .unwrap();
1739
1740 let property_list = PropertyListBuilder::new()
1741 .with_properties(vec![property.clone()])
1742 .build()
1743 .unwrap();
1744
1745 let builder = property_list.into_builder();
1746
1747 assert_eq!(builder.properties, Some(vec![property]));
1748 }
1749
1750 #[test]
1751 fn test_property_list_bytes() {
1754 let property_definition = PropertyDefinitionBuilder::new()
1755 .with_name("i dunno".into())
1756 .with_data_type(DataType::String)
1757 .with_required(true)
1758 .with_description("test".into())
1759 .build()
1760 .unwrap();
1761
1762 let reporter = ReporterBuilder::new()
1763 .with_public_key("1234".to_string())
1764 .with_authorized(true)
1765 .with_index(0)
1766 .build()
1767 .unwrap();
1768
1769 let property = PropertyBuilder::new()
1770 .with_name("taco".into())
1771 .with_record_id("taco1234".into())
1772 .with_property_definition(property_definition.clone())
1773 .with_reporters(vec![reporter.clone()])
1774 .with_current_page(0)
1775 .with_wrapped(true)
1776 .build()
1777 .unwrap();
1778
1779 let property_list = PropertyListBuilder::new()
1780 .with_properties(vec![property])
1781 .build()
1782 .unwrap();
1783
1784 test_from_bytes(property_list, PropertyList::from_bytes);
1785 }
1786
1787 #[test]
1788 fn test_property_page() {
1790 let property_value = PropertyValueBuilder::new()
1791 .with_name("egg".into())
1792 .with_data_type(DataType::Number)
1793 .with_number_value(42)
1794 .build()
1795 .unwrap();
1796
1797 let reported_value = ReportedValueBuilder::new()
1798 .with_reporter_index(0)
1799 .with_timestamp(214)
1800 .with_value(property_value)
1801 .build()
1802 .unwrap();
1803
1804 let property_page = PropertyPageBuilder::new()
1805 .with_name("egg".into())
1806 .with_record_id("egg1234".into())
1807 .with_reported_values(vec![reported_value.clone()])
1808 .build()
1809 .unwrap();
1810
1811 assert_eq!(property_page.name(), "egg");
1812 assert_eq!(property_page.record_id(), "egg1234");
1813 assert!(property_page
1814 .reported_values()
1815 .iter()
1816 .any(|x| *x == reported_value));
1817 }
1818
1819 #[test]
1820 fn test_property_page_into_builder() {
1822 let property_value = PropertyValueBuilder::new()
1823 .with_name("egg".into())
1824 .with_data_type(DataType::Number)
1825 .with_number_value(42)
1826 .build()
1827 .unwrap();
1828
1829 let reported_value = ReportedValueBuilder::new()
1830 .with_reporter_index(0)
1831 .with_timestamp(214)
1832 .with_value(property_value)
1833 .build()
1834 .unwrap();
1835
1836 let property_page = PropertyPageBuilder::new()
1837 .with_name("egg".into())
1838 .with_record_id("egg1234".into())
1839 .with_reported_values(vec![reported_value.clone()])
1840 .build()
1841 .unwrap();
1842
1843 let builder = property_page.into_builder();
1844
1845 assert_eq!(builder.name, Some("egg".to_string()));
1846 assert_eq!(builder.record_id, Some("egg1234".to_string()));
1847 assert_eq!(builder.reported_values, Some(vec![reported_value]));
1848 }
1849
1850 #[test]
1851 fn test_property_page_bytes() {
1854 let property_value = PropertyValueBuilder::new()
1855 .with_name("egg".into())
1856 .with_data_type(DataType::Number)
1857 .with_number_value(42)
1858 .build()
1859 .unwrap();
1860
1861 let reported_value = ReportedValueBuilder::new()
1862 .with_reporter_index(0)
1863 .with_timestamp(214)
1864 .with_value(property_value)
1865 .build()
1866 .unwrap();
1867
1868 let property_page = PropertyPageBuilder::new()
1869 .with_name("egg".into())
1870 .with_record_id("egg1234".into())
1871 .with_reported_values(vec![reported_value.clone()])
1872 .build()
1873 .unwrap();
1874
1875 test_from_bytes(property_page, PropertyPage::from_bytes);
1876 }
1877
1878 #[test]
1879 fn test_property_page_list() {
1881 let property_value = PropertyValueBuilder::new()
1882 .with_name("egg".into())
1883 .with_data_type(DataType::Number)
1884 .with_number_value(42)
1885 .build()
1886 .unwrap();
1887
1888 let reported_value = ReportedValueBuilder::new()
1889 .with_reporter_index(0)
1890 .with_timestamp(214)
1891 .with_value(property_value)
1892 .build()
1893 .unwrap();
1894
1895 let property_page = PropertyPageBuilder::new()
1896 .with_name("egg".into())
1897 .with_record_id("egg1234".into())
1898 .with_reported_values(vec![reported_value.clone()])
1899 .build()
1900 .unwrap();
1901
1902 let property_page_list = PropertyPageListBuilder::new()
1903 .with_property_pages(vec![property_page.clone()])
1904 .build()
1905 .unwrap();
1906
1907 assert!(property_page_list
1908 .property_pages()
1909 .iter()
1910 .any(|x| *x == property_page))
1911 }
1912
1913 #[test]
1914 fn test_property_page_list_into_builder() {
1916 let property_value = PropertyValueBuilder::new()
1917 .with_name("egg".into())
1918 .with_data_type(DataType::Number)
1919 .with_number_value(42)
1920 .build()
1921 .unwrap();
1922
1923 let reported_value = ReportedValueBuilder::new()
1924 .with_reporter_index(0)
1925 .with_timestamp(214)
1926 .with_value(property_value)
1927 .build()
1928 .unwrap();
1929
1930 let property_page = PropertyPageBuilder::new()
1931 .with_name("egg".into())
1932 .with_record_id("egg1234".into())
1933 .with_reported_values(vec![reported_value.clone()])
1934 .build()
1935 .unwrap();
1936
1937 let property_page_list = PropertyPageListBuilder::new()
1938 .with_property_pages(vec![property_page.clone()])
1939 .build()
1940 .unwrap();
1941
1942 let builder = property_page_list.into_builder();
1943
1944 assert_eq!(builder.property_pages, Some(vec![property_page]))
1945 }
1946
1947 #[test]
1948 fn test_property_page_list_bytes() {
1951 let property_value = PropertyValueBuilder::new()
1952 .with_name("egg".into())
1953 .with_data_type(DataType::Number)
1954 .with_number_value(42)
1955 .build()
1956 .unwrap();
1957
1958 let reported_value = ReportedValueBuilder::new()
1959 .with_reporter_index(0)
1960 .with_timestamp(214)
1961 .with_value(property_value)
1962 .build()
1963 .unwrap();
1964
1965 let property_page = PropertyPageBuilder::new()
1966 .with_name("egg".into())
1967 .with_record_id("egg1234".into())
1968 .with_reported_values(vec![reported_value.clone()])
1969 .build()
1970 .unwrap();
1971
1972 let property_page_list = PropertyPageListBuilder::new()
1973 .with_property_pages(vec![property_page.clone()])
1974 .build()
1975 .unwrap();
1976
1977 test_from_bytes(property_page_list, PropertyPageList::from_bytes);
1978 }
1979
1980 #[test]
1981 fn test_proposal_builder() {
1983 let proposal = ProposalBuilder::new()
1984 .with_record_id("egg1234".into())
1985 .with_timestamp(214)
1986 .with_issuing_agent("james".into())
1987 .with_receiving_agent("joe".into())
1988 .with_role(Role::Owner)
1989 .with_properties(vec!["wet".into()])
1990 .with_status(Status::Open)
1991 .with_terms("a term".into())
1992 .build()
1993 .unwrap();
1994
1995 assert_eq!(proposal.record_id(), "egg1234");
1996 assert_eq!(*proposal.timestamp(), 214);
1997 assert_eq!(proposal.issuing_agent(), "james");
1998 assert_eq!(proposal.receiving_agent(), "joe");
1999 assert_eq!(*proposal.role(), Role::Owner);
2000 assert!(proposal.properties().iter().any(|x| x == "wet"));
2001 assert_eq!(*proposal.status(), Status::Open);
2002 assert_eq!(proposal.terms(), "a term");
2003 }
2004
2005 #[test]
2006 fn test_proposal_into_builder() {
2008 let proposal = ProposalBuilder::new()
2009 .with_record_id("egg1234".into())
2010 .with_timestamp(214)
2011 .with_issuing_agent("james".into())
2012 .with_receiving_agent("joe".into())
2013 .with_role(Role::Owner)
2014 .with_properties(vec!["wet".into()])
2015 .with_status(Status::Open)
2016 .with_terms("a term".into())
2017 .build()
2018 .unwrap();
2019
2020 let builder = proposal.into_builder();
2021
2022 assert_eq!(builder.record_id, Some("egg1234".to_string()));
2023 assert_eq!(builder.timestamp, Some(214));
2024 assert_eq!(builder.issuing_agent, Some("james".to_string()));
2025 assert_eq!(builder.receiving_agent, Some("joe".to_string()));
2026 assert_eq!(builder.role, Some(Role::Owner));
2027 assert_eq!(builder.properties, Some(vec!["wet".to_string()]));
2028 assert_eq!(builder.status, Some(Status::Open));
2029 assert_eq!(builder.terms, Some("a term".to_string()));
2030 }
2031
2032 #[test]
2033 fn test_proposal_bytes() {
2036 let proposal = ProposalBuilder::new()
2037 .with_record_id("egg1234".into())
2038 .with_timestamp(214)
2039 .with_issuing_agent("james".into())
2040 .with_receiving_agent("joe".into())
2041 .with_role(Role::Owner)
2042 .with_properties(vec!["wet".into(), "gets everywhere".into()])
2043 .with_status(Status::Open)
2044 .with_terms("a term".into())
2045 .build()
2046 .unwrap();
2047
2048 test_from_bytes(proposal, Proposal::from_bytes);
2049 }
2050
2051 #[test]
2052 fn test_proposal_list() {
2054 let proposal = ProposalBuilder::new()
2055 .with_record_id("egg1234".into())
2056 .with_timestamp(214)
2057 .with_issuing_agent("james".into())
2058 .with_receiving_agent("joe".into())
2059 .with_role(Role::Owner)
2060 .with_properties(vec!["wet".into(), "gets everywhere".into()])
2061 .with_status(Status::Open)
2062 .with_terms("a term".into())
2063 .build()
2064 .unwrap();
2065
2066 let proposal_list = ProposalListBuilder::new()
2067 .with_proposals(vec![proposal.clone()])
2068 .build()
2069 .unwrap();
2070
2071 assert!(proposal_list.proposals().iter().any(|x| *x == proposal));
2072 }
2073
2074 #[test]
2075 fn test_proposal_list_into_builder() {
2077 let proposal = ProposalBuilder::new()
2078 .with_record_id("egg1234".into())
2079 .with_timestamp(214)
2080 .with_issuing_agent("james".into())
2081 .with_receiving_agent("joe".into())
2082 .with_role(Role::Owner)
2083 .with_properties(vec!["wet".into(), "gets everywhere".into()])
2084 .with_status(Status::Open)
2085 .with_terms("a term".into())
2086 .build()
2087 .unwrap();
2088
2089 let proposal_list = ProposalListBuilder::new()
2090 .with_proposals(vec![proposal.clone()])
2091 .build()
2092 .unwrap();
2093
2094 let builder = proposal_list.into_builder();
2095
2096 assert_eq!(builder.proposals, Some(vec![proposal]));
2097 }
2098
2099 #[test]
2100 fn test_proposal_list_bytes() {
2103 let proposal = ProposalBuilder::new()
2104 .with_record_id("egg1234".into())
2105 .with_timestamp(214)
2106 .with_issuing_agent("james".into())
2107 .with_receiving_agent("joe".into())
2108 .with_role(Role::Owner)
2109 .with_properties(vec!["wet".into(), "gets everywhere".into()])
2110 .with_status(Status::Open)
2111 .with_terms("a term".into())
2112 .build()
2113 .unwrap();
2114
2115 let proposal_list = ProposalListBuilder::new()
2116 .with_proposals(vec![proposal.clone()])
2117 .build()
2118 .unwrap();
2119
2120 test_from_bytes(proposal_list, ProposalList::from_bytes);
2121 }
2122
2123 #[test]
2124 fn test_record_builder() {
2126 let associated_agent = AssociatedAgentBuilder::new()
2127 .with_agent_id("agent1234".into())
2128 .with_timestamp(2132)
2129 .build()
2130 .unwrap();
2131
2132 let record = RecordBuilder::new()
2133 .with_record_id("egg1234".into())
2134 .with_schema("egg".into())
2135 .with_owners(vec![associated_agent.clone()])
2136 .with_custodians(vec![associated_agent.clone()])
2137 .with_field_final(false)
2138 .build()
2139 .unwrap();
2140
2141 assert_eq!(record.record_id(), "egg1234");
2142 assert_eq!(record.schema(), "egg");
2143 assert!(record.owners().iter().any(|x| *x == associated_agent));
2144 assert!(record.custodians().iter().any(|x| *x == associated_agent));
2145 assert_eq!(*record.field_final(), false);
2146 }
2147
2148 #[test]
2149 fn test_record_into_builder() {
2151 let associated_agent = AssociatedAgentBuilder::new()
2152 .with_agent_id("agent1234".into())
2153 .with_timestamp(2132)
2154 .build()
2155 .unwrap();
2156
2157 let record = RecordBuilder::new()
2158 .with_record_id("egg1234".into())
2159 .with_schema("egg".into())
2160 .with_owners(vec![associated_agent.clone()])
2161 .with_custodians(vec![associated_agent.clone()])
2162 .with_field_final(false)
2163 .build()
2164 .unwrap();
2165
2166 let builder = record.into_builder();
2167
2168 assert_eq!(builder.record_id, Some("egg1234".to_string()));
2169 assert_eq!(builder.schema, Some("egg".to_string()));
2170 assert_eq!(builder.owners, Some(vec![associated_agent.clone()]));
2171 assert_eq!(builder.custodians, Some(vec![associated_agent.clone()]));
2172 assert_eq!(builder.field_final, Some(false));
2173 }
2174
2175 #[test]
2176 fn test_record_bytes() {
2179 let associated_agent = AssociatedAgentBuilder::new()
2180 .with_agent_id("agent1234".into())
2181 .with_timestamp(2132)
2182 .build()
2183 .unwrap();
2184
2185 let record = RecordBuilder::new()
2186 .with_record_id("egg1234".into())
2187 .with_schema("egg".into())
2188 .with_owners(vec![associated_agent.clone()])
2189 .with_custodians(vec![associated_agent.clone()])
2190 .with_field_final(false)
2191 .build()
2192 .unwrap();
2193
2194 test_from_bytes(record, Record::from_bytes);
2195 }
2196
2197 #[test]
2198 fn test_record_list() {
2200 let associated_agent = AssociatedAgentBuilder::new()
2201 .with_agent_id("agent1234".into())
2202 .with_timestamp(2132)
2203 .build()
2204 .unwrap();
2205
2206 let record = RecordBuilder::new()
2207 .with_record_id("egg1234".into())
2208 .with_schema("egg".into())
2209 .with_owners(vec![associated_agent.clone()])
2210 .with_custodians(vec![associated_agent.clone()])
2211 .with_field_final(false)
2212 .build()
2213 .unwrap();
2214
2215 let record_list = RecordListBuilder::new()
2216 .with_records(vec![record.clone()])
2217 .build()
2218 .unwrap();
2219
2220 assert!(record_list.records().iter().any(|x| *x == record));
2221 }
2222
2223 #[test]
2224 fn test_record_list_into_builder() {
2226 let associated_agent = AssociatedAgentBuilder::new()
2227 .with_agent_id("agent1234".into())
2228 .with_timestamp(2132)
2229 .build()
2230 .unwrap();
2231
2232 let record = RecordBuilder::new()
2233 .with_record_id("egg1234".into())
2234 .with_schema("egg".into())
2235 .with_owners(vec![associated_agent.clone()])
2236 .with_custodians(vec![associated_agent.clone()])
2237 .with_field_final(false)
2238 .build()
2239 .unwrap();
2240
2241 let record_list = RecordListBuilder::new()
2242 .with_records(vec![record.clone()])
2243 .build()
2244 .unwrap();
2245
2246 let builder = record_list.into_builder();
2247
2248 assert_eq!(builder.records, Some(vec![record]));
2249 }
2250
2251 #[test]
2252 fn test_record_list_bytes() {
2255 let associated_agent = AssociatedAgentBuilder::new()
2256 .with_agent_id("agent1234".into())
2257 .with_timestamp(2132)
2258 .build()
2259 .unwrap();
2260
2261 let record = RecordBuilder::new()
2262 .with_record_id("egg1234".into())
2263 .with_schema("egg".into())
2264 .with_owners(vec![associated_agent.clone()])
2265 .with_custodians(vec![associated_agent.clone()])
2266 .with_field_final(false)
2267 .build()
2268 .unwrap();
2269
2270 let record_list = RecordListBuilder::new()
2271 .with_records(vec![record.clone()])
2272 .build()
2273 .unwrap();
2274
2275 test_from_bytes(record_list, RecordList::from_bytes);
2276 }
2277
2278 #[test]
2279 fn test_associated_agent_into_builder() {
2281 let associated_agent = AssociatedAgentBuilder::new()
2282 .with_agent_id("agent1234".into())
2283 .with_timestamp(2132)
2284 .build()
2285 .unwrap();
2286
2287 let builder = associated_agent.into_builder();
2288
2289 assert_eq!(builder.agent_id, Some("agent1234".to_string()));
2290 assert_eq!(builder.timestamp, Some(2132));
2291 }
2292}