sabre_sdk/protocol/
state.rs

1// Copyright 2019 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
15use protobuf::Message;
16use protobuf::RepeatedField;
17
18use std::error::Error as StdError;
19
20use crate::protos;
21use crate::protos::{
22    FromBytes, FromNative, FromProto, IntoBytes, IntoNative, IntoProto, ProtoConversionError,
23};
24
25/// Native implementation for Version
26#[derive(Default, Debug, Clone, PartialEq)]
27pub struct Version {
28    version: String,
29    contract_sha512: String,
30    creator: String,
31}
32
33impl Version {
34    pub fn version(&self) -> &String {
35        &self.version
36    }
37
38    pub fn contract_sha512(&self) -> &String {
39        &self.contract_sha512
40    }
41
42    pub fn creator(&self) -> &String {
43        &self.creator
44    }
45
46    pub fn into_builder(self) -> VersionBuilder {
47        VersionBuilder::new()
48            .with_version(self.version)
49            .with_contract_sha512(self.contract_sha512)
50            .with_creator(self.creator)
51    }
52}
53
54impl FromProto<protos::contract_registry::ContractRegistry_Version> for Version {
55    fn from_proto(
56        proto: protos::contract_registry::ContractRegistry_Version,
57    ) -> Result<Self, ProtoConversionError> {
58        Ok(Version {
59            version: proto.get_version().to_string(),
60            contract_sha512: proto.get_contract_sha512().to_string(),
61            creator: proto.get_creator().to_string(),
62        })
63    }
64}
65
66impl FromNative<Version> for protos::contract_registry::ContractRegistry_Version {
67    fn from_native(native: Version) -> Result<Self, ProtoConversionError> {
68        let mut proto = protos::contract_registry::ContractRegistry_Version::new();
69
70        proto.set_version(native.version().to_string());
71        proto.set_contract_sha512(native.contract_sha512().to_string());
72        proto.set_creator(native.creator().to_string());
73
74        Ok(proto)
75    }
76}
77
78impl IntoProto<protos::contract_registry::ContractRegistry_Version> for Version {}
79impl IntoNative<Version> for protos::contract_registry::ContractRegistry_Version {}
80
81#[derive(Debug)]
82pub enum VersionBuildError {
83    MissingField(String),
84}
85
86impl StdError for VersionBuildError {
87    fn description(&self) -> &str {
88        match *self {
89            VersionBuildError::MissingField(ref msg) => msg,
90        }
91    }
92}
93
94impl std::fmt::Display for VersionBuildError {
95    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
96        match *self {
97            VersionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
98        }
99    }
100}
101
102/// Builder used to create a Version
103#[derive(Default, Clone)]
104pub struct VersionBuilder {
105    version: Option<String>,
106    contract_sha512: Option<String>,
107    creator: Option<String>,
108}
109
110impl VersionBuilder {
111    pub fn new() -> Self {
112        VersionBuilder::default()
113    }
114
115    pub fn with_version(mut self, version: String) -> VersionBuilder {
116        self.version = Some(version);
117        self
118    }
119
120    pub fn with_contract_sha512(mut self, contract_sha512: String) -> VersionBuilder {
121        self.contract_sha512 = Some(contract_sha512);
122        self
123    }
124
125    pub fn with_creator(mut self, creator: String) -> VersionBuilder {
126        self.creator = Some(creator);
127        self
128    }
129
130    pub fn build(self) -> Result<Version, VersionBuildError> {
131        let version = self.version.ok_or_else(|| {
132            VersionBuildError::MissingField("'versions' field is required".to_string())
133        })?;
134
135        let contract_sha512 = self.contract_sha512.ok_or_else(|| {
136            VersionBuildError::MissingField("'contract_sha512' field is required".to_string())
137        })?;
138
139        let creator = self.creator.ok_or_else(|| {
140            VersionBuildError::MissingField("'creator' field is required".to_string())
141        })?;
142
143        Ok(Version {
144            version,
145            contract_sha512,
146            creator,
147        })
148    }
149}
150
151/// Native implementation for ContractRegistry
152#[derive(Default, Debug, Clone, PartialEq)]
153pub struct ContractRegistry {
154    name: String,
155    versions: Vec<Version>,
156    owners: Vec<String>,
157}
158
159impl ContractRegistry {
160    pub fn name(&self) -> &String {
161        &self.name
162    }
163
164    pub fn versions(&self) -> &[Version] {
165        &self.versions
166    }
167
168    pub fn owners(&self) -> &[String] {
169        &self.owners
170    }
171
172    pub fn into_builder(self) -> ContractRegistryBuilder {
173        ContractRegistryBuilder::new()
174            .with_name(self.name)
175            .with_versions(self.versions)
176            .with_owners(self.owners)
177    }
178}
179
180impl FromProto<protos::contract_registry::ContractRegistry> for ContractRegistry {
181    fn from_proto(
182        proto: protos::contract_registry::ContractRegistry,
183    ) -> Result<Self, ProtoConversionError> {
184        Ok(ContractRegistry {
185            name: proto.get_name().to_string(),
186            versions: proto
187                .get_versions()
188                .to_vec()
189                .into_iter()
190                .map(Version::from_proto)
191                .collect::<Result<Vec<Version>, ProtoConversionError>>()?,
192            owners: proto.get_owners().to_vec(),
193        })
194    }
195}
196
197impl FromNative<ContractRegistry> for protos::contract_registry::ContractRegistry {
198    fn from_native(contract_registry: ContractRegistry) -> Result<Self, ProtoConversionError> {
199        let mut proto = protos::contract_registry::ContractRegistry::new();
200        proto.set_name(contract_registry.name().to_string());
201        proto.set_versions(RepeatedField::from_vec(
202            contract_registry
203                .versions()
204                .to_vec()
205                .into_iter()
206                .map(Version::into_proto)
207                .collect::<Result<
208                    Vec<protos::contract_registry::ContractRegistry_Version>,
209                    ProtoConversionError,
210                >>()?,
211        ));
212        proto.set_owners(RepeatedField::from_vec(contract_registry.owners().to_vec()));
213
214        Ok(proto)
215    }
216}
217
218impl FromBytes<ContractRegistry> for ContractRegistry {
219    fn from_bytes(bytes: &[u8]) -> Result<ContractRegistry, ProtoConversionError> {
220        let proto: protos::contract_registry::ContractRegistry = Message::parse_from_bytes(bytes)
221            .map_err(|_| {
222            ProtoConversionError::SerializationError(
223                "Unable to get ContractRegistry from bytes".to_string(),
224            )
225        })?;
226        proto.into_native()
227    }
228}
229
230impl IntoBytes for ContractRegistry {
231    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
232        let proto = self.into_proto()?;
233        let bytes = proto.write_to_bytes().map_err(|_| {
234            ProtoConversionError::SerializationError(
235                "Unable to get bytes from ContractRegistry".to_string(),
236            )
237        })?;
238        Ok(bytes)
239    }
240}
241
242impl IntoProto<protos::contract_registry::ContractRegistry> for ContractRegistry {}
243impl IntoNative<ContractRegistry> for protos::contract_registry::ContractRegistry {}
244
245#[derive(Debug)]
246pub enum ContractRegistryBuildError {
247    MissingField(String),
248}
249
250impl StdError for ContractRegistryBuildError {
251    fn description(&self) -> &str {
252        match *self {
253            ContractRegistryBuildError::MissingField(ref msg) => msg,
254        }
255    }
256}
257
258impl std::fmt::Display for ContractRegistryBuildError {
259    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
260        match *self {
261            ContractRegistryBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
262        }
263    }
264}
265
266/// Builder used to create a ContractRegistry
267#[derive(Default, Clone)]
268pub struct ContractRegistryBuilder {
269    name: Option<String>,
270    versions: Vec<Version>,
271    owners: Vec<String>,
272}
273
274impl ContractRegistryBuilder {
275    pub fn new() -> Self {
276        ContractRegistryBuilder::default()
277    }
278
279    pub fn with_name(mut self, name: String) -> ContractRegistryBuilder {
280        self.name = Some(name);
281        self
282    }
283
284    pub fn with_versions(mut self, versions: Vec<Version>) -> ContractRegistryBuilder {
285        self.versions = versions;
286        self
287    }
288
289    pub fn with_owners(mut self, owners: Vec<String>) -> ContractRegistryBuilder {
290        self.owners = owners;
291        self
292    }
293
294    pub fn build(self) -> Result<ContractRegistry, ContractRegistryBuildError> {
295        let name = self.name.ok_or_else(|| {
296            ContractRegistryBuildError::MissingField("'name' field is required".to_string())
297        })?;
298
299        let versions = self.versions;
300
301        let owners = {
302            if !self.owners.is_empty() {
303                self.owners
304            } else {
305                return Err(ContractRegistryBuildError::MissingField(
306                    "'owners' field is required".to_string(),
307                ));
308            }
309        };
310
311        Ok(ContractRegistry {
312            name,
313            versions,
314            owners,
315        })
316    }
317}
318
319/// Native implementation for ContractRegistryList
320#[derive(Default, Debug, Clone, PartialEq)]
321pub struct ContractRegistryList {
322    registries: Vec<ContractRegistry>,
323}
324
325impl ContractRegistryList {
326    pub fn registries(&self) -> &[ContractRegistry] {
327        &self.registries
328    }
329}
330
331impl FromProto<protos::contract_registry::ContractRegistryList> for ContractRegistryList {
332    fn from_proto(
333        proto: protos::contract_registry::ContractRegistryList,
334    ) -> Result<Self, ProtoConversionError> {
335        Ok(ContractRegistryList {
336            registries: proto
337                .get_registries()
338                .to_vec()
339                .into_iter()
340                .map(ContractRegistry::from_proto)
341                .collect::<Result<Vec<ContractRegistry>, ProtoConversionError>>()?,
342        })
343    }
344}
345
346impl FromNative<ContractRegistryList> for protos::contract_registry::ContractRegistryList {
347    fn from_native(
348        contract_registry_list: ContractRegistryList,
349    ) -> Result<Self, ProtoConversionError> {
350        let mut proto = protos::contract_registry::ContractRegistryList::new();
351        proto.set_registries(
352            RepeatedField::from_vec(
353                contract_registry_list
354                    .registries()
355                    .to_vec()
356                    .into_iter()
357                    .map(ContractRegistry::into_proto)
358                    .collect::<Result<
359                        Vec<protos::contract_registry::ContractRegistry>,
360                        ProtoConversionError,
361                    >>()?,
362            ),
363        );
364
365        Ok(proto)
366    }
367}
368
369impl FromBytes<ContractRegistryList> for ContractRegistryList {
370    fn from_bytes(bytes: &[u8]) -> Result<ContractRegistryList, ProtoConversionError> {
371        let proto: protos::contract_registry::ContractRegistryList =
372            Message::parse_from_bytes(bytes).map_err(|_| {
373                ProtoConversionError::SerializationError(
374                    "Unable to get ContractRegistryList from bytes".to_string(),
375                )
376            })?;
377        proto.into_native()
378    }
379}
380
381impl IntoBytes for ContractRegistryList {
382    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
383        let proto = self.into_proto()?;
384        let bytes = proto.write_to_bytes().map_err(|_| {
385            ProtoConversionError::SerializationError(
386                "Unable to get bytes from ContractRegistryList".to_string(),
387            )
388        })?;
389        Ok(bytes)
390    }
391}
392
393impl IntoProto<protos::contract_registry::ContractRegistryList> for ContractRegistryList {}
394impl IntoNative<ContractRegistryList> for protos::contract_registry::ContractRegistryList {}
395
396#[derive(Debug)]
397pub enum ContractRegistryListBuildError {
398    MissingField(String),
399}
400
401impl StdError for ContractRegistryListBuildError {
402    fn description(&self) -> &str {
403        match *self {
404            ContractRegistryListBuildError::MissingField(ref msg) => msg,
405        }
406    }
407}
408
409impl std::fmt::Display for ContractRegistryListBuildError {
410    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
411        match *self {
412            ContractRegistryListBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
413        }
414    }
415}
416
417/// Builder used to create a ContractRegistryList
418#[derive(Default, Clone)]
419pub struct ContractRegistryListBuilder {
420    registries: Vec<ContractRegistry>,
421}
422
423impl ContractRegistryListBuilder {
424    pub fn new() -> Self {
425        ContractRegistryListBuilder::default()
426    }
427
428    pub fn with_registries(
429        mut self,
430        registries: Vec<ContractRegistry>,
431    ) -> ContractRegistryListBuilder {
432        self.registries = registries;
433        self
434    }
435
436    pub fn build(self) -> Result<ContractRegistryList, ContractRegistryListBuildError> {
437        let registries = self.registries;
438
439        Ok(ContractRegistryList { registries })
440    }
441}
442
443/// Native implementation for Permission
444#[derive(Default, Debug, Clone, PartialEq)]
445pub struct Permission {
446    contract_name: String,
447    read: bool,
448    write: bool,
449}
450
451impl Permission {
452    pub fn contract_name(&self) -> &String {
453        &self.contract_name
454    }
455
456    pub fn read(&self) -> bool {
457        self.read
458    }
459
460    pub fn write(&self) -> bool {
461        self.write
462    }
463
464    pub fn into_builder(self) -> PermissionBuilder {
465        PermissionBuilder::new()
466            .with_contract_name(self.contract_name)
467            .with_read(self.read)
468            .with_write(self.write)
469    }
470}
471
472impl FromProto<protos::namespace_registry::NamespaceRegistry_Permission> for Permission {
473    fn from_proto(
474        proto: protos::namespace_registry::NamespaceRegistry_Permission,
475    ) -> Result<Self, ProtoConversionError> {
476        Ok(Permission {
477            contract_name: proto.get_contract_name().to_string(),
478            read: proto.get_read(),
479            write: proto.get_write(),
480        })
481    }
482}
483
484impl FromNative<Permission> for protos::namespace_registry::NamespaceRegistry_Permission {
485    fn from_native(native: Permission) -> Result<Self, ProtoConversionError> {
486        let mut proto = protos::namespace_registry::NamespaceRegistry_Permission::new();
487
488        proto.set_contract_name(native.contract_name().to_string());
489        proto.set_read(native.read());
490        proto.set_write(native.write());
491
492        Ok(proto)
493    }
494}
495
496impl IntoProto<protos::namespace_registry::NamespaceRegistry_Permission> for Permission {}
497impl IntoNative<Permission> for protos::namespace_registry::NamespaceRegistry_Permission {}
498
499#[derive(Debug)]
500pub enum PermissionBuildError {
501    MissingField(String),
502}
503
504impl StdError for PermissionBuildError {
505    fn description(&self) -> &str {
506        match *self {
507            PermissionBuildError::MissingField(ref msg) => msg,
508        }
509    }
510}
511
512impl std::fmt::Display for PermissionBuildError {
513    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
514        match *self {
515            PermissionBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
516        }
517    }
518}
519
520/// Builder used to create a Permission
521#[derive(Default, Clone)]
522pub struct PermissionBuilder {
523    contract_name: Option<String>,
524    read: Option<bool>,
525    write: Option<bool>,
526}
527
528impl PermissionBuilder {
529    pub fn new() -> Self {
530        PermissionBuilder::default()
531    }
532
533    pub fn with_contract_name(mut self, contract_name: String) -> PermissionBuilder {
534        self.contract_name = Some(contract_name);
535        self
536    }
537
538    pub fn with_read(mut self, read: bool) -> PermissionBuilder {
539        self.read = Some(read);
540        self
541    }
542
543    pub fn with_write(mut self, write: bool) -> PermissionBuilder {
544        self.write = Some(write);
545        self
546    }
547
548    pub fn build(self) -> Result<Permission, PermissionBuildError> {
549        let contract_name = self.contract_name.ok_or_else(|| {
550            PermissionBuildError::MissingField("'contract_name' field is required".to_string())
551        })?;
552
553        let read = self.read.unwrap_or_default();
554
555        let write = self.write.unwrap_or_default();
556
557        Ok(Permission {
558            contract_name,
559            read,
560            write,
561        })
562    }
563}
564
565/// Native implementation for NamespaceRegistry
566#[derive(Default, Debug, Clone, PartialEq)]
567pub struct NamespaceRegistry {
568    namespace: String,
569    owners: Vec<String>,
570    permissions: Vec<Permission>,
571}
572
573impl NamespaceRegistry {
574    pub fn namespace(&self) -> &String {
575        &self.namespace
576    }
577
578    pub fn owners(&self) -> &[String] {
579        &self.owners
580    }
581
582    pub fn permissions(&self) -> &[Permission] {
583        &self.permissions
584    }
585
586    pub fn into_builder(self) -> NamespaceRegistryBuilder {
587        NamespaceRegistryBuilder::new()
588            .with_namespace(self.namespace)
589            .with_owners(self.owners)
590            .with_permissions(self.permissions)
591    }
592}
593
594impl FromProto<protos::namespace_registry::NamespaceRegistry> for NamespaceRegistry {
595    fn from_proto(
596        proto: protos::namespace_registry::NamespaceRegistry,
597    ) -> Result<Self, ProtoConversionError> {
598        Ok(NamespaceRegistry {
599            namespace: proto.get_namespace().to_string(),
600            owners: proto.get_owners().to_vec(),
601            permissions: proto
602                .get_permissions()
603                .to_vec()
604                .into_iter()
605                .map(Permission::from_proto)
606                .collect::<Result<Vec<Permission>, ProtoConversionError>>()?,
607        })
608    }
609}
610
611impl FromNative<NamespaceRegistry> for protos::namespace_registry::NamespaceRegistry {
612    fn from_native(native: NamespaceRegistry) -> Result<Self, ProtoConversionError> {
613        let mut proto = protos::namespace_registry::NamespaceRegistry::new();
614        proto.set_namespace(native.namespace().to_string());
615        proto.set_owners(RepeatedField::from_vec(native.owners().to_vec()));
616        proto.set_permissions(RepeatedField::from_vec(
617            native
618                .permissions()
619                .to_vec()
620                .into_iter()
621                .map(Permission::into_proto)
622                .collect::<Result<
623                    Vec<protos::namespace_registry::NamespaceRegistry_Permission>,
624                    ProtoConversionError,
625                >>()?,
626        ));
627
628        Ok(proto)
629    }
630}
631
632impl FromBytes<NamespaceRegistry> for NamespaceRegistry {
633    fn from_bytes(bytes: &[u8]) -> Result<NamespaceRegistry, ProtoConversionError> {
634        let proto: protos::namespace_registry::NamespaceRegistry = Message::parse_from_bytes(bytes)
635            .map_err(|_| {
636                ProtoConversionError::SerializationError(
637                    "Unable to get NamespaceRegistry from bytes".to_string(),
638                )
639            })?;
640        proto.into_native()
641    }
642}
643
644impl IntoBytes for NamespaceRegistry {
645    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
646        let proto = self.into_proto()?;
647        let bytes = proto.write_to_bytes().map_err(|_| {
648            ProtoConversionError::SerializationError(
649                "Unable to get bytes from NamespaceRegistry".to_string(),
650            )
651        })?;
652        Ok(bytes)
653    }
654}
655
656impl IntoProto<protos::namespace_registry::NamespaceRegistry> for NamespaceRegistry {}
657impl IntoNative<NamespaceRegistry> for protos::namespace_registry::NamespaceRegistry {}
658
659#[derive(Debug)]
660pub enum NamespaceRegistryBuildError {
661    MissingField(String),
662}
663
664impl StdError for NamespaceRegistryBuildError {
665    fn description(&self) -> &str {
666        match *self {
667            NamespaceRegistryBuildError::MissingField(ref msg) => msg,
668        }
669    }
670}
671
672impl std::fmt::Display for NamespaceRegistryBuildError {
673    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
674        match *self {
675            NamespaceRegistryBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
676        }
677    }
678}
679
680/// Builder used to create a NamespaceRegistry
681#[derive(Default, Clone)]
682pub struct NamespaceRegistryBuilder {
683    namespace: Option<String>,
684    owners: Vec<String>,
685    permissions: Vec<Permission>,
686}
687
688impl NamespaceRegistryBuilder {
689    pub fn new() -> Self {
690        NamespaceRegistryBuilder::default()
691    }
692
693    pub fn with_namespace(mut self, namespace: String) -> NamespaceRegistryBuilder {
694        self.namespace = Some(namespace);
695        self
696    }
697
698    pub fn with_owners(mut self, owners: Vec<String>) -> NamespaceRegistryBuilder {
699        self.owners = owners;
700        self
701    }
702
703    pub fn with_permissions(mut self, permissions: Vec<Permission>) -> NamespaceRegistryBuilder {
704        self.permissions = permissions;
705        self
706    }
707
708    pub fn build(self) -> Result<NamespaceRegistry, NamespaceRegistryBuildError> {
709        let namespace = self.namespace.ok_or_else(|| {
710            NamespaceRegistryBuildError::MissingField("'namespace' field is required".to_string())
711        })?;
712
713        let owners = {
714            if !self.owners.is_empty() {
715                self.owners
716            } else {
717                return Err(NamespaceRegistryBuildError::MissingField(
718                    "'owners' field is required".to_string(),
719                ));
720            }
721        };
722
723        let permissions = self.permissions;
724
725        Ok(NamespaceRegistry {
726            namespace,
727            owners,
728            permissions,
729        })
730    }
731}
732
733// Native implementation for NamespaceRegistryList
734#[derive(Default, Debug, Clone, PartialEq)]
735pub struct NamespaceRegistryList {
736    registries: Vec<NamespaceRegistry>,
737}
738
739impl NamespaceRegistryList {
740    pub fn registries(&self) -> &[NamespaceRegistry] {
741        &self.registries
742    }
743}
744
745impl FromProto<protos::namespace_registry::NamespaceRegistryList> for NamespaceRegistryList {
746    fn from_proto(
747        proto: protos::namespace_registry::NamespaceRegistryList,
748    ) -> Result<Self, ProtoConversionError> {
749        Ok(NamespaceRegistryList {
750            registries: proto
751                .get_registries()
752                .to_vec()
753                .into_iter()
754                .map(NamespaceRegistry::from_proto)
755                .collect::<Result<Vec<NamespaceRegistry>, ProtoConversionError>>()?,
756        })
757    }
758}
759
760impl FromNative<NamespaceRegistryList> for protos::namespace_registry::NamespaceRegistryList {
761    fn from_native(
762        namespace_registry_list: NamespaceRegistryList,
763    ) -> Result<Self, ProtoConversionError> {
764        let mut proto = protos::namespace_registry::NamespaceRegistryList::new();
765        proto.set_registries(
766            RepeatedField::from_vec(
767                namespace_registry_list
768                    .registries()
769                    .to_vec()
770                    .into_iter()
771                    .map(NamespaceRegistry::into_proto)
772                    .collect::<Result<
773                        Vec<protos::namespace_registry::NamespaceRegistry>,
774                        ProtoConversionError,
775                    >>()?,
776            ),
777        );
778
779        Ok(proto)
780    }
781}
782
783impl FromBytes<NamespaceRegistryList> for NamespaceRegistryList {
784    fn from_bytes(bytes: &[u8]) -> Result<NamespaceRegistryList, ProtoConversionError> {
785        let proto: protos::namespace_registry::NamespaceRegistryList =
786            Message::parse_from_bytes(bytes).map_err(|_| {
787                ProtoConversionError::SerializationError(
788                    "Unable to get NamespaceRegistryList from bytes".to_string(),
789                )
790            })?;
791        proto.into_native()
792    }
793}
794
795impl IntoBytes for NamespaceRegistryList {
796    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
797        let proto = self.into_proto()?;
798        let bytes = proto.write_to_bytes().map_err(|_| {
799            ProtoConversionError::SerializationError(
800                "Unable to get bytes from NamespaceRegistryList".to_string(),
801            )
802        })?;
803        Ok(bytes)
804    }
805}
806
807impl IntoProto<protos::namespace_registry::NamespaceRegistryList> for NamespaceRegistryList {}
808impl IntoNative<NamespaceRegistryList> for protos::namespace_registry::NamespaceRegistryList {}
809
810#[derive(Debug)]
811pub enum NamespaceRegistryListBuildError {
812    MissingField(String),
813}
814
815impl StdError for NamespaceRegistryListBuildError {
816    fn description(&self) -> &str {
817        match *self {
818            NamespaceRegistryListBuildError::MissingField(ref msg) => msg,
819        }
820    }
821}
822
823impl std::fmt::Display for NamespaceRegistryListBuildError {
824    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
825        match *self {
826            NamespaceRegistryListBuildError::MissingField(ref s) => {
827                write!(f, "MissingField: {}", s)
828            }
829        }
830    }
831}
832
833/// Builder used to create a NamespaceRegistryList
834#[derive(Default, Clone)]
835pub struct NamespaceRegistryListBuilder {
836    registries: Vec<NamespaceRegistry>,
837}
838
839impl NamespaceRegistryListBuilder {
840    pub fn new() -> Self {
841        NamespaceRegistryListBuilder::default()
842    }
843
844    pub fn with_registries(
845        mut self,
846        registries: Vec<NamespaceRegistry>,
847    ) -> NamespaceRegistryListBuilder {
848        self.registries = registries;
849        self
850    }
851
852    pub fn build(self) -> Result<NamespaceRegistryList, NamespaceRegistryListBuildError> {
853        let registries = self.registries;
854
855        Ok(NamespaceRegistryList { registries })
856    }
857}
858
859/// Native implementation for Contract
860#[derive(Default, Debug, Clone, PartialEq)]
861pub struct Contract {
862    name: String,
863    version: String,
864    inputs: Vec<String>,
865    outputs: Vec<String>,
866    creator: String,
867    contract: Vec<u8>,
868}
869
870impl Contract {
871    pub fn name(&self) -> &String {
872        &self.name
873    }
874
875    pub fn version(&self) -> &String {
876        &self.version
877    }
878
879    pub fn inputs(&self) -> &[String] {
880        &self.inputs
881    }
882
883    pub fn outputs(&self) -> &[String] {
884        &self.outputs
885    }
886
887    pub fn creator(&self) -> &String {
888        &self.creator
889    }
890
891    pub fn contract(&self) -> &[u8] {
892        &self.contract
893    }
894
895    pub fn into_builder(self) -> ContractBuilder {
896        ContractBuilder::new()
897            .with_name(self.name)
898            .with_version(self.version)
899            .with_inputs(self.inputs)
900            .with_outputs(self.outputs)
901            .with_creator(self.creator)
902            .with_contract(self.contract)
903    }
904}
905
906impl FromProto<protos::contract::Contract> for Contract {
907    fn from_proto(proto: protos::contract::Contract) -> Result<Self, ProtoConversionError> {
908        Ok(Contract {
909            name: proto.get_name().to_string(),
910            version: proto.get_version().to_string(),
911            inputs: proto.get_inputs().to_vec(),
912            outputs: proto.get_outputs().to_vec(),
913            creator: proto.get_creator().to_string(),
914            contract: proto.get_contract().to_vec(),
915        })
916    }
917}
918
919impl FromNative<Contract> for protos::contract::Contract {
920    fn from_native(contract: Contract) -> Result<Self, ProtoConversionError> {
921        let mut proto = protos::contract::Contract::new();
922
923        proto.set_name(contract.name().to_string());
924        proto.set_version(contract.version().to_string());
925        proto.set_inputs(RepeatedField::from_vec(contract.inputs().to_vec()));
926        proto.set_outputs(RepeatedField::from_vec(contract.outputs().to_vec()));
927        proto.set_creator(contract.creator().to_string());
928        proto.set_contract(contract.contract().to_vec());
929
930        Ok(proto)
931    }
932}
933
934impl FromBytes<Contract> for Contract {
935    fn from_bytes(bytes: &[u8]) -> Result<Contract, ProtoConversionError> {
936        let proto: protos::contract::Contract = Message::parse_from_bytes(bytes).map_err(|_| {
937            ProtoConversionError::SerializationError(
938                "Unable to get Contract from bytes".to_string(),
939            )
940        })?;
941        proto.into_native()
942    }
943}
944
945impl IntoBytes for Contract {
946    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
947        let proto = self.into_proto()?;
948        let bytes = proto.write_to_bytes().map_err(|_| {
949            ProtoConversionError::SerializationError(
950                "Unable to get bytes from Contract".to_string(),
951            )
952        })?;
953        Ok(bytes)
954    }
955}
956
957impl IntoProto<protos::contract::Contract> for Contract {}
958impl IntoNative<Contract> for protos::contract::Contract {}
959
960#[derive(Debug)]
961pub enum ContractBuildError {
962    MissingField(String),
963}
964
965impl StdError for ContractBuildError {
966    fn description(&self) -> &str {
967        match *self {
968            ContractBuildError::MissingField(ref msg) => msg,
969        }
970    }
971}
972
973impl std::fmt::Display for ContractBuildError {
974    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
975        match *self {
976            ContractBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
977        }
978    }
979}
980
981/// Builder used to create a Contract
982#[derive(Default, Clone)]
983pub struct ContractBuilder {
984    name: Option<String>,
985    version: Option<String>,
986    inputs: Vec<String>,
987    outputs: Vec<String>,
988    creator: Option<String>,
989    contract: Vec<u8>,
990}
991
992impl ContractBuilder {
993    pub fn new() -> Self {
994        ContractBuilder::default()
995    }
996
997    pub fn with_name(mut self, name: String) -> ContractBuilder {
998        self.name = Some(name);
999        self
1000    }
1001
1002    pub fn with_version(mut self, version: String) -> ContractBuilder {
1003        self.version = Some(version);
1004        self
1005    }
1006
1007    pub fn with_inputs(mut self, inputs: Vec<String>) -> ContractBuilder {
1008        self.inputs = inputs;
1009        self
1010    }
1011
1012    pub fn with_outputs(mut self, outputs: Vec<String>) -> ContractBuilder {
1013        self.outputs = outputs;
1014        self
1015    }
1016
1017    pub fn with_creator(mut self, creator: String) -> ContractBuilder {
1018        self.creator = Some(creator);
1019        self
1020    }
1021
1022    pub fn with_contract(mut self, contract: Vec<u8>) -> ContractBuilder {
1023        self.contract = contract;
1024        self
1025    }
1026
1027    pub fn build(self) -> Result<Contract, ContractBuildError> {
1028        let name = self.name.ok_or_else(|| {
1029            ContractBuildError::MissingField("'name' field is required".to_string())
1030        })?;
1031
1032        let version = self.version.ok_or_else(|| {
1033            ContractBuildError::MissingField("'version' field is required".to_string())
1034        })?;
1035
1036        let creator = self.creator.ok_or_else(|| {
1037            ContractBuildError::MissingField("'version' field is required".to_string())
1038        })?;
1039
1040        let inputs = {
1041            if !self.inputs.is_empty() {
1042                self.inputs
1043            } else {
1044                return Err(ContractBuildError::MissingField(
1045                    "'inputs' field is required".to_string(),
1046                ));
1047            }
1048        };
1049
1050        let outputs = {
1051            if !self.outputs.is_empty() {
1052                self.outputs
1053            } else {
1054                return Err(ContractBuildError::MissingField(
1055                    "'outputs' field is required".to_string(),
1056                ));
1057            }
1058        };
1059
1060        let contract = {
1061            if !self.contract.is_empty() {
1062                self.contract
1063            } else {
1064                return Err(ContractBuildError::MissingField(
1065                    "'contract' field is required".to_string(),
1066                ));
1067            }
1068        };
1069
1070        Ok(Contract {
1071            name,
1072            version,
1073            inputs,
1074            outputs,
1075            creator,
1076            contract,
1077        })
1078    }
1079}
1080
1081// Native implementation for ContractList
1082#[derive(Default, Debug, Clone, PartialEq)]
1083pub struct ContractList {
1084    contracts: Vec<Contract>,
1085}
1086
1087impl ContractList {
1088    pub fn contracts(&self) -> &[Contract] {
1089        &self.contracts
1090    }
1091}
1092
1093impl FromProto<protos::contract::ContractList> for ContractList {
1094    fn from_proto(proto: protos::contract::ContractList) -> Result<Self, ProtoConversionError> {
1095        Ok(ContractList {
1096            contracts: proto
1097                .get_contracts()
1098                .to_vec()
1099                .into_iter()
1100                .map(Contract::from_proto)
1101                .collect::<Result<Vec<Contract>, ProtoConversionError>>()?,
1102        })
1103    }
1104}
1105
1106impl FromNative<ContractList> for protos::contract::ContractList {
1107    fn from_native(contract_list: ContractList) -> Result<Self, ProtoConversionError> {
1108        let mut proto = protos::contract::ContractList::new();
1109        proto.set_contracts(RepeatedField::from_vec(
1110            contract_list
1111                .contracts()
1112                .to_vec()
1113                .into_iter()
1114                .map(Contract::into_proto)
1115                .collect::<Result<Vec<protos::contract::Contract>, ProtoConversionError>>()?,
1116        ));
1117
1118        Ok(proto)
1119    }
1120}
1121
1122impl FromBytes<ContractList> for ContractList {
1123    fn from_bytes(bytes: &[u8]) -> Result<ContractList, ProtoConversionError> {
1124        let proto: protos::contract::ContractList =
1125            Message::parse_from_bytes(bytes).map_err(|_| {
1126                ProtoConversionError::SerializationError(
1127                    "Unable to get ContractList from bytes".to_string(),
1128                )
1129            })?;
1130        proto.into_native()
1131    }
1132}
1133
1134impl IntoBytes for ContractList {
1135    fn into_bytes(self) -> Result<Vec<u8>, ProtoConversionError> {
1136        let proto = self.into_proto()?;
1137        let bytes = proto.write_to_bytes().map_err(|_| {
1138            ProtoConversionError::SerializationError(
1139                "Unable to get bytes from ContractList".to_string(),
1140            )
1141        })?;
1142        Ok(bytes)
1143    }
1144}
1145
1146impl IntoProto<protos::contract::ContractList> for ContractList {}
1147impl IntoNative<ContractList> for protos::contract::ContractList {}
1148
1149#[derive(Debug)]
1150pub enum ContractListBuildError {
1151    MissingField(String),
1152}
1153
1154impl StdError for ContractListBuildError {
1155    fn description(&self) -> &str {
1156        match *self {
1157            ContractListBuildError::MissingField(ref msg) => msg,
1158        }
1159    }
1160}
1161
1162impl std::fmt::Display for ContractListBuildError {
1163    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1164        match *self {
1165            ContractListBuildError::MissingField(ref s) => write!(f, "MissingField: {}", s),
1166        }
1167    }
1168}
1169
1170/// Builder used to create a ContractList
1171#[derive(Default, Clone)]
1172pub struct ContractListBuilder {
1173    contracts: Vec<Contract>,
1174}
1175
1176impl ContractListBuilder {
1177    pub fn new() -> Self {
1178        ContractListBuilder::default()
1179    }
1180
1181    pub fn with_contracts(mut self, contracts: Vec<Contract>) -> ContractListBuilder {
1182        self.contracts = contracts;
1183        self
1184    }
1185
1186    pub fn build(self) -> Result<ContractList, ContractListBuildError> {
1187        let contracts = self.contracts;
1188
1189        Ok(ContractList { contracts })
1190    }
1191}
1192
1193#[cfg(test)]
1194mod tests {
1195    use super::*;
1196
1197    #[test]
1198    // check that a contract registry is built correctly
1199    fn check_contract_registry() {
1200        let builder = VersionBuilder::new();
1201        let version = builder
1202            .with_version("0.0.0".to_string())
1203            .with_contract_sha512("sha512".to_string())
1204            .with_creator("The Creator".to_string())
1205            .build()
1206            .unwrap();
1207
1208        let builder = ContractRegistryBuilder::new();
1209        let contract_registry = builder
1210            .with_name("Tests".to_string())
1211            .with_versions(vec![version.clone()])
1212            .with_owners(vec!["owner".to_string()])
1213            .build()
1214            .unwrap();
1215
1216        assert_eq!(contract_registry.name(), "Tests");
1217        assert_eq!(contract_registry.versions(), [version]);
1218        assert_eq!(contract_registry.owners(), ["owner"]);
1219    }
1220
1221    #[test]
1222    // check that a contract registry can be converted to bytes and back
1223    fn check_contract_registry_bytes() {
1224        let builder = VersionBuilder::new();
1225        let version = builder
1226            .with_version("0.0.0".to_string())
1227            .with_contract_sha512("sha512".to_string())
1228            .with_creator("The Creator".to_string())
1229            .build()
1230            .unwrap();
1231
1232        let builder = ContractRegistryBuilder::new();
1233        let original = builder
1234            .with_name("Tests".to_string())
1235            .with_versions(vec![version.clone()])
1236            .with_owners(vec!["owner".to_string()])
1237            .build()
1238            .unwrap();
1239
1240        let bytes = original.clone().into_bytes().unwrap();
1241
1242        let contract_registry = ContractRegistry::from_bytes(&bytes).unwrap();
1243        assert_eq!(contract_registry, original);
1244    }
1245
1246    #[test]
1247    // check that a contract registry can be converted into builder
1248    fn check_contract_registry_into_builder() {
1249        let builder = VersionBuilder::new();
1250        let version = builder
1251            .with_version("0.0.0".to_string())
1252            .with_contract_sha512("sha512".to_string())
1253            .with_creator("The Creator".to_string())
1254            .build()
1255            .unwrap();
1256
1257        let builder = ContractRegistryBuilder::new();
1258        let contract_registry = builder
1259            .with_name("Tests".to_string())
1260            .with_versions(vec![version.clone()])
1261            .with_owners(vec!["owner".to_string()])
1262            .build()
1263            .unwrap();
1264
1265        let builder = contract_registry.into_builder();
1266
1267        assert_eq!(builder.name, Some("Tests".to_string()));
1268        assert_eq!(builder.versions, [version]);
1269        assert_eq!(builder.owners, ["owner"]);
1270    }
1271
1272    #[test]
1273    // check that a contract registry list is built correctly
1274    fn check_contract_registry_list() {
1275        let builder = VersionBuilder::new();
1276        let version = builder
1277            .with_version("0.0.0".to_string())
1278            .with_contract_sha512("sha512".to_string())
1279            .with_creator("The Creator".to_string())
1280            .build()
1281            .unwrap();
1282
1283        let builder = ContractRegistryBuilder::new();
1284        let contract_registry = builder
1285            .with_name("Tests".to_string())
1286            .with_versions(vec![version.clone()])
1287            .with_owners(vec!["owner".to_string()])
1288            .build()
1289            .unwrap();
1290
1291        let build = ContractRegistryListBuilder::new();
1292        let contract_registry_list = build
1293            .with_registries(vec![contract_registry.clone()])
1294            .build()
1295            .unwrap();
1296
1297        assert_eq!(contract_registry_list.registries(), [contract_registry]);
1298    }
1299
1300    #[test]
1301    // check that a contract registry list can be converted to bytes and back
1302    fn check_contract_registry_bytes_list() {
1303        let builder = VersionBuilder::new();
1304        let version = builder
1305            .with_version("0.0.0".to_string())
1306            .with_contract_sha512("sha512".to_string())
1307            .with_creator("The Creator".to_string())
1308            .build()
1309            .unwrap();
1310
1311        let builder = ContractRegistryBuilder::new();
1312        let contract_registry = builder
1313            .with_name("Tests".to_string())
1314            .with_versions(vec![version.clone()])
1315            .with_owners(vec!["owner".to_string()])
1316            .build()
1317            .unwrap();
1318
1319        let build = ContractRegistryListBuilder::new();
1320        let original = build
1321            .with_registries(vec![contract_registry.clone()])
1322            .build()
1323            .unwrap();
1324
1325        let bytes = original.clone().into_bytes().unwrap();
1326
1327        let contract_registry_list = ContractRegistryList::from_bytes(&bytes).unwrap();
1328        assert_eq!(contract_registry_list, original);
1329    }
1330
1331    #[test]
1332    // check that a namespace registry is built correctly
1333    fn check_namespace_registry() {
1334        let builder = PermissionBuilder::new();
1335        let permission = builder
1336            .with_contract_name("Test".to_string())
1337            .with_read(true)
1338            .with_write(true)
1339            .build()
1340            .unwrap();
1341
1342        let builder = NamespaceRegistryBuilder::new();
1343        let namespace_registry = builder
1344            .with_namespace("Tests".to_string())
1345            .with_owners(vec!["owner".to_string()])
1346            .with_permissions(vec![permission.clone()])
1347            .build()
1348            .unwrap();
1349
1350        assert_eq!(namespace_registry.namespace(), "Tests");
1351        assert_eq!(namespace_registry.permissions(), [permission]);
1352        assert_eq!(namespace_registry.owners(), ["owner"]);
1353    }
1354
1355    #[test]
1356    // check that a namespace registry can be converted to bytes and back
1357    fn check_namespace_registry_bytes() {
1358        let builder = PermissionBuilder::new();
1359        let permission = builder
1360            .with_contract_name("Test".to_string())
1361            .with_read(true)
1362            .with_write(true)
1363            .build()
1364            .unwrap();
1365
1366        let builder = NamespaceRegistryBuilder::new();
1367        let original = builder
1368            .with_namespace("Tests".to_string())
1369            .with_owners(vec!["owner".to_string()])
1370            .with_permissions(vec![permission.clone()])
1371            .build()
1372            .unwrap();
1373
1374        let bytes = original.clone().into_bytes().unwrap();
1375
1376        let namespace_registry = NamespaceRegistry::from_bytes(&bytes).unwrap();
1377        assert_eq!(namespace_registry, original);
1378    }
1379
1380    #[test]
1381    // check that a namespace registry can be conveted into a builder
1382    fn check_namespace_registry_into_build() {
1383        let builder = PermissionBuilder::new();
1384        let permission = builder
1385            .with_contract_name("Test".to_string())
1386            .with_read(true)
1387            .with_write(true)
1388            .build()
1389            .unwrap();
1390
1391        let builder = NamespaceRegistryBuilder::new();
1392        let namespace_registry = builder
1393            .with_namespace("Tests".to_string())
1394            .with_owners(vec!["owner".to_string()])
1395            .with_permissions(vec![permission.clone()])
1396            .build()
1397            .unwrap();
1398
1399        let builder = namespace_registry.into_builder();
1400
1401        assert_eq!(builder.namespace, Some("Tests".to_string()));
1402        assert_eq!(builder.permissions, [permission]);
1403        assert_eq!(builder.owners, ["owner"]);
1404    }
1405
1406    #[test]
1407    // check that a namespace registry list is built correctly
1408    fn check_namespace_registry_list() {
1409        let builder = PermissionBuilder::new();
1410        let permission = builder
1411            .with_contract_name("Test".to_string())
1412            .with_read(true)
1413            .with_write(true)
1414            .build()
1415            .unwrap();
1416
1417        let builder = NamespaceRegistryBuilder::new();
1418        let namespace_registry = builder
1419            .with_namespace("Tests".to_string())
1420            .with_owners(vec!["owner".to_string()])
1421            .with_permissions(vec![permission.clone()])
1422            .build()
1423            .unwrap();
1424
1425        let build = NamespaceRegistryListBuilder::new();
1426        let namespace_registry_list = build
1427            .with_registries(vec![namespace_registry.clone()])
1428            .build()
1429            .unwrap();
1430
1431        assert_eq!(namespace_registry_list.registries(), [namespace_registry]);
1432    }
1433
1434    #[test]
1435    // check that a namespace registry list can be converted to bytes and back
1436    fn check_namespace_registry_bytes_list() {
1437        let builder = PermissionBuilder::new();
1438        let permission = builder
1439            .with_contract_name("Test".to_string())
1440            .with_read(true)
1441            .with_write(true)
1442            .build()
1443            .unwrap();
1444
1445        let builder = NamespaceRegistryBuilder::new();
1446        let namespace_registry = builder
1447            .with_namespace("Tests".to_string())
1448            .with_owners(vec!["owner".to_string()])
1449            .with_permissions(vec![permission.clone()])
1450            .build()
1451            .unwrap();
1452
1453        let build = NamespaceRegistryListBuilder::new();
1454        let original = build
1455            .with_registries(vec![namespace_registry.clone()])
1456            .build()
1457            .unwrap();
1458
1459        let bytes = original.clone().into_bytes().unwrap();
1460
1461        let namespace_registry_list = NamespaceRegistryList::from_bytes(&bytes).unwrap();
1462        assert_eq!(namespace_registry_list, original);
1463    }
1464
1465    #[test]
1466    // check that a contract is built correctly
1467    fn check_contract() {
1468        let builder = ContractBuilder::new();
1469        let contract = builder
1470            .with_name("Tests".to_string())
1471            .with_version("0.0.0".to_string())
1472            .with_inputs(vec!["input1".to_string(), "input2".to_string()])
1473            .with_outputs(vec!["output1".to_string(), "output2".to_string()])
1474            .with_creator("The Creator".to_string())
1475            .with_contract(b"test_contract".to_vec())
1476            .build()
1477            .unwrap();
1478
1479        assert_eq!(contract.name(), "Tests");
1480        assert_eq!(contract.version(), "0.0.0");
1481        assert_eq!(
1482            contract.inputs(),
1483            ["input1".to_string(), "input2".to_string()]
1484        );
1485        assert_eq!(
1486            contract.outputs(),
1487            ["output1".to_string(), "output2".to_string()]
1488        );
1489        assert_eq!(contract.creator(), "The Creator");
1490        assert_eq!(contract.contract(), b"test_contract");
1491    }
1492
1493    #[test]
1494    // check that a contract can be converted to bytes and back
1495    fn check_contract_bytes() {
1496        let builder = ContractBuilder::new();
1497        let original = builder
1498            .with_name("Tests".to_string())
1499            .with_version("0.0.0".to_string())
1500            .with_inputs(vec!["input1".to_string(), "input2".to_string()])
1501            .with_outputs(vec!["output1".to_string(), "output2".to_string()])
1502            .with_creator("The Creator".to_string())
1503            .with_contract(b"test_contract".to_vec())
1504            .build()
1505            .unwrap();
1506
1507        let bytes = original.clone().into_bytes().unwrap();
1508
1509        let contract = Contract::from_bytes(&bytes).unwrap();
1510        assert_eq!(contract, original);
1511    }
1512
1513    #[test]
1514    // check that the contract can be converted into a builder
1515    fn check_contract_into_builder() {
1516        let builder = ContractBuilder::new();
1517        let contract = builder
1518            .with_name("Tests".to_string())
1519            .with_version("0.0.0".to_string())
1520            .with_inputs(vec!["input1".to_string(), "input2".to_string()])
1521            .with_outputs(vec!["output1".to_string(), "output2".to_string()])
1522            .with_creator("The Creator".to_string())
1523            .with_contract(b"test_contract".to_vec())
1524            .build()
1525            .unwrap();
1526
1527        let builder = contract.into_builder();
1528
1529        assert_eq!(builder.name, Some("Tests".to_string()));
1530        assert_eq!(builder.version, Some("0.0.0".to_string()));
1531        assert_eq!(builder.inputs, ["input1".to_string(), "input2".to_string()]);
1532        assert_eq!(
1533            builder.outputs,
1534            ["output1".to_string(), "output2".to_string()]
1535        );
1536        assert_eq!(builder.creator, Some("The Creator".to_string()));
1537        assert_eq!(builder.contract, b"test_contract".to_vec());
1538    }
1539
1540    #[test]
1541    // check that a contract list is built correctly
1542    fn check_contract_list() {
1543        let builder = ContractBuilder::new();
1544        let contract = builder
1545            .with_name("Tests".to_string())
1546            .with_version("0.0.0".to_string())
1547            .with_inputs(vec!["input1".to_string(), "input2".to_string()])
1548            .with_outputs(vec!["output1".to_string(), "output2".to_string()])
1549            .with_creator("The Creator".to_string())
1550            .with_contract(b"test_contract".to_vec())
1551            .build()
1552            .unwrap();
1553
1554        let builder = ContractListBuilder::new();
1555        let contract_list = builder
1556            .with_contracts(vec![contract.clone()])
1557            .build()
1558            .unwrap();
1559
1560        assert_eq!(contract_list.contracts(), [contract]);
1561    }
1562
1563    #[test]
1564    // check that a contract list can be converted to bytes and back
1565    fn check_contract_list_bytes() {
1566        let builder = ContractBuilder::new();
1567        let contract = builder
1568            .with_name("Tests".to_string())
1569            .with_version("0.0.0".to_string())
1570            .with_inputs(vec!["input1".to_string(), "input2".to_string()])
1571            .with_outputs(vec!["output1".to_string(), "output2".to_string()])
1572            .with_creator("The Creator".to_string())
1573            .with_contract(b"test_contract".to_vec())
1574            .build()
1575            .unwrap();
1576
1577        let builder = ContractListBuilder::new();
1578        let original = builder
1579            .with_contracts(vec![contract.clone()])
1580            .build()
1581            .unwrap();
1582
1583        let bytes = original.clone().into_bytes().unwrap();
1584
1585        let contract_list = ContractList::from_bytes(&bytes).unwrap();
1586        assert_eq!(contract_list, original);
1587    }
1588}