1use crate::data::value::{DamlEnum, DamlRecord, DamlVariant};
2use crate::data::{DamlError, DamlResult};
3use crate::grpc_protobuf::com::daml::ledger::api::v1::value::Sum;
4use crate::grpc_protobuf::com::daml::ledger::api::v1::{
5 gen_map, map, Enum, GenMap, List, Map, Optional, Record, Value, Variant,
6};
7use crate::util;
8use crate::util::Required;
9use std::convert::{TryFrom, TryInto};
10
11use crate::nat::Nat;
12use crate::primitive_types::{
13 DamlBool, DamlContractId, DamlDate, DamlFixedNumeric, DamlGenMap, DamlInt64, DamlList, DamlNumeric, DamlOptional,
14 DamlParty, DamlText, DamlTextMap, DamlTimestamp, DamlUnit,
15};
16use crate::serialize::{
17 DamlDeserializableType, DamlDeserializeFrom, DamlDeserializeInto, DamlSerializableType, DamlSerializeFrom,
18 DamlSerializeInto,
19};
20use itertools::Itertools;
21use std::cmp::Ordering;
22use std::str::FromStr;
23
24#[derive(Debug, Eq, PartialEq, Clone)]
33pub enum DamlValue {
34 Record(DamlRecord),
36 Variant(DamlVariant),
38 Enum(DamlEnum),
40 ContractId(DamlContractId),
42 List(DamlList<DamlValue>),
44 Int64(DamlInt64),
46 Numeric(DamlNumeric),
48 Text(DamlText),
50 Timestamp(DamlTimestamp),
52 Party(DamlParty),
54 Bool(DamlBool),
56 Unit,
58 Date(DamlDate),
60 Optional(Option<Box<DamlValue>>),
62 Map(DamlTextMap<DamlValue>),
64 GenMap(DamlGenMap<DamlValue, DamlValue>),
66}
67
68impl DamlValue {
69 pub fn new_record(record: impl Into<DamlRecord>) -> Self {
71 DamlValue::Record(record.into())
72 }
73
74 pub fn new_variant(variant: impl Into<DamlVariant>) -> Self {
76 DamlValue::Variant(variant.into())
77 }
78
79 pub fn new_enum(enum_variant: impl Into<DamlEnum>) -> Self {
81 DamlValue::Enum(enum_variant.into())
82 }
83
84 pub fn new_contract_id(contract_id: impl Into<DamlContractId>) -> Self {
86 DamlValue::ContractId(contract_id.into())
87 }
88
89 pub fn new_list(list: impl Into<DamlList<Self>>) -> Self {
91 DamlValue::List(list.into())
92 }
93
94 pub fn new_int64(value: impl Into<DamlInt64>) -> Self {
96 DamlValue::Int64(value.into())
97 }
98
99 pub fn new_numeric(numeric: impl Into<DamlNumeric>) -> Self {
101 DamlValue::Numeric(numeric.into())
102 }
103
104 pub fn new_text(text: impl Into<DamlText>) -> Self {
106 DamlValue::Text(text.into())
107 }
108
109 pub fn new_timestamp(timestamp: impl Into<DamlTimestamp>) -> Self {
111 DamlValue::Timestamp(timestamp.into())
112 }
113
114 pub fn new_party(party: impl Into<DamlParty>) -> Self {
116 DamlValue::Party(party.into())
117 }
118
119 pub fn new_bool(value: DamlBool) -> Self {
121 DamlValue::Bool(value)
122 }
123
124 pub const fn new_unit() -> Self {
126 DamlValue::Unit
127 }
128
129 pub fn new_date(date: impl Into<DamlDate>) -> Self {
131 DamlValue::Date(date.into())
132 }
133
134 pub fn new_optional(optional: Option<Self>) -> Self {
136 DamlValue::Optional(optional.map(Box::new))
137 }
138
139 pub fn new_map(map: impl Into<DamlTextMap<Self>>) -> Self {
141 DamlValue::Map(map.into())
142 }
143
144 pub fn new_genmap(map: impl Into<DamlGenMap<Self, Self>>) -> Self {
146 DamlValue::GenMap(map.into())
147 }
148
149 pub fn try_unit(&self) -> DamlResult<()> {
154 match self {
155 DamlValue::Unit => Ok(()),
156 _ => Err(self.make_unexpected_type_error("Unit")),
157 }
158 }
159
160 pub fn try_unit_ref(&self) -> DamlResult<&()> {
165 match self {
166 DamlValue::Unit => Ok(&()),
167 _ => Err(self.make_unexpected_type_error("Unit")),
168 }
169 }
170
171 pub fn try_date(&self) -> DamlResult<DamlDate> {
176 match *self {
177 DamlValue::Date(d) => Ok(d),
178 _ => Err(self.make_unexpected_type_error("Date")),
179 }
180 }
181
182 pub fn try_date_ref(&self) -> DamlResult<&DamlDate> {
187 match self {
188 DamlValue::Date(d) => Ok(d),
189 _ => Err(self.make_unexpected_type_error("Date")),
190 }
191 }
192
193 pub fn try_int64(&self) -> DamlResult<DamlInt64> {
198 match self {
199 DamlValue::Int64(i) => Ok(*i),
200 _ => Err(self.make_unexpected_type_error("Int64")),
201 }
202 }
203
204 pub fn try_int64_ref(&self) -> DamlResult<&DamlInt64> {
209 match self {
210 DamlValue::Int64(i) => Ok(i),
211 _ => Err(self.make_unexpected_type_error("Int64")),
212 }
213 }
214
215 pub fn try_numeric(&self) -> DamlResult<&DamlNumeric> {
220 match self {
221 DamlValue::Numeric(d) => Ok(d),
222 _ => Err(self.make_unexpected_type_error("Numeric")),
223 }
224 }
225
226 pub fn try_numeric_clone(&self) -> DamlResult<DamlNumeric> {
231 match self {
232 DamlValue::Numeric(d) => Ok(d.clone()),
233 _ => Err(self.make_unexpected_type_error("Numeric")),
234 }
235 }
236
237 pub fn try_bool(&self) -> DamlResult<DamlBool> {
242 match self {
243 DamlValue::Bool(b) => Ok(*b),
244 _ => Err(self.make_unexpected_type_error("Bool")),
245 }
246 }
247
248 pub fn try_bool_ref(&self) -> DamlResult<&DamlBool> {
253 match self {
254 DamlValue::Bool(b) => Ok(b),
255 _ => Err(self.make_unexpected_type_error("Bool")),
256 }
257 }
258
259 pub fn try_text(&self) -> DamlResult<&DamlText> {
264 match self {
265 DamlValue::Text(s) => Ok(s),
266 _ => Err(self.make_unexpected_type_error("Text")),
267 }
268 }
269
270 pub fn try_timestamp(&self) -> DamlResult<DamlTimestamp> {
275 match *self {
276 DamlValue::Timestamp(ts) => Ok(ts),
277 _ => Err(self.make_unexpected_type_error("Timestamp")),
278 }
279 }
280
281 pub fn try_timestamp_ref(&self) -> DamlResult<&DamlTimestamp> {
286 match self {
287 DamlValue::Timestamp(ts) => Ok(ts),
288 _ => Err(self.make_unexpected_type_error("Timestamp")),
289 }
290 }
291
292 pub fn try_party(&self) -> DamlResult<&DamlParty> {
297 match self {
298 DamlValue::Party(party) => Ok(party),
299 _ => Err(self.make_unexpected_type_error("Party")),
300 }
301 }
302
303 pub fn try_contract_id(&self) -> DamlResult<&DamlContractId> {
308 match self {
309 DamlValue::ContractId(contract_id) => Ok(contract_id),
310 _ => Err(self.make_unexpected_type_error("ContractId")),
311 }
312 }
313
314 pub fn try_record(&self) -> DamlResult<&DamlRecord> {
319 match self {
320 DamlValue::Record(r) => Ok(r),
321 _ => Err(self.make_unexpected_type_error("Record")),
322 }
323 }
324
325 pub fn try_list(&self) -> DamlResult<&DamlList<Self>> {
330 match self {
331 DamlValue::List(l) => Ok(l),
332 _ => Err(self.make_unexpected_type_error("List")),
333 }
334 }
335
336 pub fn try_variant(&self) -> DamlResult<&DamlVariant> {
341 match self {
342 DamlValue::Variant(v) => Ok(v),
343 _ => Err(self.make_unexpected_type_error("Variant")),
344 }
345 }
346
347 pub fn try_enum(&self) -> DamlResult<&DamlEnum> {
352 match self {
353 DamlValue::Enum(e) => Ok(e),
354 _ => Err(self.make_unexpected_type_error("Enum")),
355 }
356 }
357
358 pub fn try_optional(&self) -> DamlResult<Option<&Self>> {
363 match self {
364 DamlValue::Optional(opt) => Ok(opt.as_deref()),
365 _ => Err(self.make_unexpected_type_error("Optional")),
366 }
367 }
368
369 pub fn try_map(&self) -> DamlResult<&DamlTextMap<Self>> {
374 match self {
375 DamlValue::Map(m) => Ok(m),
376 _ => Err(self.make_unexpected_type_error("Map")),
377 }
378 }
379
380 pub fn try_genmap(&self) -> DamlResult<&DamlGenMap<Self, Self>> {
385 match self {
386 DamlValue::GenMap(m) => Ok(m),
387 _ => Err(self.make_unexpected_type_error("GenMap")),
388 }
389 }
390
391 pub fn try_take_record(self) -> DamlResult<DamlRecord> {
396 match self {
397 DamlValue::Record(r) => Ok(r),
398 _ => Err(self.make_unexpected_type_error("Record")),
399 }
400 }
401
402 pub fn try_take_variant(self) -> DamlResult<DamlVariant> {
407 match self {
408 DamlValue::Variant(v) => Ok(v),
409 _ => Err(self.make_unexpected_type_error("Variant")),
410 }
411 }
412
413 pub fn try_take_enum(self) -> DamlResult<DamlEnum> {
418 match self {
419 DamlValue::Enum(e) => Ok(e),
420 _ => Err(self.make_unexpected_type_error("Enum")),
421 }
422 }
423
424 pub fn try_take_list(self) -> DamlResult<DamlList<Self>> {
429 match self {
430 DamlValue::List(l) => Ok(l),
431 _ => Err(self.make_unexpected_type_error("List")),
432 }
433 }
434
435 pub fn try_take_map(self) -> DamlResult<DamlTextMap<Self>> {
440 match self {
441 DamlValue::Map(m) => Ok(m),
442 _ => Err(self.make_unexpected_type_error("Map")),
443 }
444 }
445
446 pub fn try_take_genmap(self) -> DamlResult<DamlGenMap<Self, Self>> {
451 match self {
452 DamlValue::GenMap(m) => Ok(m),
453 _ => Err(self.make_unexpected_type_error("Map")),
454 }
455 }
456
457 pub fn try_take_optional(self) -> DamlResult<Option<Self>> {
462 match self {
463 DamlValue::Optional(o) => Ok(o.map(|b| *b)),
464 _ => Err(self.make_unexpected_type_error("Optional")),
465 }
466 }
467
468 pub fn variant_name(&self) -> &str {
470 match self {
471 DamlValue::Record(_) => "Record",
472 DamlValue::Variant(_) => "Variant",
473 DamlValue::Enum(_) => "Enum",
474 DamlValue::ContractId(_) => "ContractId",
475 DamlValue::List(_) => "List",
476 DamlValue::Int64(_) => "Int64",
477 DamlValue::Numeric(_) => "Numeric",
478 DamlValue::Text(_) => "Text",
479 DamlValue::Timestamp(_) => "Timestamp",
480 DamlValue::Party(_) => "Party",
481 DamlValue::Bool(_) => "Bool",
482 DamlValue::Unit => "Unit",
483 DamlValue::Date(_) => "Date",
484 DamlValue::Optional(_) => "Optional",
485 DamlValue::Map(_) => "Map",
486 DamlValue::GenMap(_) => "GenMap",
487 }
488 }
489
490 pub fn extract<'a, R, F>(&'a self, f: F) -> DamlResult<R>
534 where
535 F: FnOnce(&'a DamlRecord) -> DamlResult<R>,
536 {
537 f(self.try_record()?)
538 }
539
540 fn make_unexpected_type_error(&self, expected: &str) -> DamlError {
541 DamlError::UnexpectedType(expected.to_owned(), self.variant_name().to_owned())
542 }
543}
544
545impl From<()> for DamlValue {
546 fn from(_: ()) -> Self {
547 Self::new_unit()
548 }
549}
550
551impl From<bool> for DamlValue {
552 fn from(b: bool) -> Self {
553 Self::new_bool(b)
554 }
555}
556
557impl From<&str> for DamlValue {
558 fn from(s: &str) -> Self {
559 Self::new_text(s)
560 }
561}
562
563impl From<String> for DamlValue {
564 fn from(s: String) -> Self {
565 Self::new_text(s)
566 }
567}
568
569impl From<u8> for DamlValue {
570 fn from(i: u8) -> Self {
571 Self::new_int64(i)
572 }
573}
574
575impl From<i8> for DamlValue {
576 fn from(i: i8) -> Self {
577 Self::new_int64(i)
578 }
579}
580
581impl From<u16> for DamlValue {
582 fn from(i: u16) -> Self {
583 Self::new_int64(i)
584 }
585}
586
587impl From<i16> for DamlValue {
588 fn from(i: i16) -> Self {
589 Self::new_int64(i)
590 }
591}
592
593impl From<u32> for DamlValue {
594 fn from(i: u32) -> Self {
595 Self::new_int64(i)
596 }
597}
598
599impl From<i32> for DamlValue {
600 fn from(i: i32) -> Self {
601 Self::new_int64(i)
602 }
603}
604
605impl From<i64> for DamlValue {
606 fn from(i: i64) -> Self {
607 Self::new_int64(i)
608 }
609}
610impl TryFrom<f32> for DamlValue {
611 type Error = DamlError;
612
613 fn try_from(d: f32) -> DamlResult<Self> {
614 Ok(Self::new_numeric(DamlNumeric::try_from(d)?))
615 }
616}
617impl TryFrom<f64> for DamlValue {
618 type Error = DamlError;
619
620 fn try_from(d: f64) -> DamlResult<Self> {
621 Ok(Self::new_numeric(DamlNumeric::try_from(d)?))
622 }
623}
624
625impl DamlSerializeFrom<DamlUnit> for DamlValue {
626 fn serialize_from(_: DamlUnit) -> DamlValue {
627 Self::new_unit()
628 }
629}
630
631impl DamlSerializeFrom<DamlBool> for DamlValue {
632 fn serialize_from(b: DamlBool) -> DamlValue {
633 Self::new_bool(b)
634 }
635}
636
637impl DamlSerializeFrom<DamlInt64> for DamlValue {
638 fn serialize_from(i: DamlInt64) -> DamlValue {
639 Self::new_int64(i)
640 }
641}
642
643impl DamlSerializeFrom<DamlText> for DamlValue {
644 fn serialize_from(text: DamlText) -> DamlValue {
645 Self::new_text(text)
646 }
647}
648
649impl DamlSerializeFrom<DamlParty> for DamlValue {
650 fn serialize_from(party: DamlParty) -> DamlValue {
651 Self::new_party(party.party)
652 }
653}
654
655impl DamlSerializeFrom<DamlContractId> for DamlValue {
656 fn serialize_from(contract_id: DamlContractId) -> DamlValue {
657 Self::new_contract_id(contract_id.contract_id)
658 }
659}
660
661impl<T> DamlSerializeFrom<DamlFixedNumeric<T>> for DamlValue
662where
663 T: DamlSerializableType + Nat,
664{
665 fn serialize_from(numeric: DamlFixedNumeric<T>) -> DamlValue {
666 Self::new_numeric(numeric.value)
667 }
668}
669
670impl DamlSerializeFrom<DamlTimestamp> for DamlValue {
671 fn serialize_from(timestamp: DamlTimestamp) -> DamlValue {
672 Self::new_timestamp(timestamp)
673 }
674}
675
676impl DamlSerializeFrom<DamlDate> for DamlValue {
677 fn serialize_from(date: DamlDate) -> DamlValue {
678 Self::new_date(date)
679 }
680}
681
682impl<T> DamlSerializeFrom<Box<T>> for DamlValue
683where
684 T: DamlSerializableType + DamlSerializeInto<DamlValue>,
685{
686 fn serialize_from(boxed: Box<T>) -> DamlValue {
687 T::serialize_into(*boxed)
688 }
689}
690
691impl<T> DamlSerializeFrom<DamlOptional<T>> for DamlValue
692where
693 T: DamlSerializableType + DamlSerializeInto<DamlValue>,
694{
695 fn serialize_from(optional: DamlOptional<T>) -> DamlValue {
696 DamlValue::new_optional(optional.map(T::serialize_into))
697 }
698}
699
700impl<T> DamlSerializeFrom<DamlList<T>> for DamlValue
701where
702 T: DamlSerializableType + DamlSerializeInto<DamlValue>,
703{
704 fn serialize_from(list: DamlList<T>) -> DamlValue {
705 DamlValue::new_list(list.into_iter().map(T::serialize_into).collect::<DamlList<_>>())
706 }
707}
708
709impl<K, V> DamlSerializeFrom<DamlGenMap<K, V>> for DamlValue
710where
711 K: DamlSerializableType + DamlSerializeInto<DamlValue>,
712 V: DamlSerializableType + DamlSerializeInto<DamlValue>,
713{
714 fn serialize_from(gen_map: DamlGenMap<K, V>) -> DamlValue {
715 DamlValue::new_genmap(
716 gen_map
717 .into_iter()
718 .map(|(k, v)| (K::serialize_into(k), V::serialize_into(v)))
719 .collect::<DamlGenMap<_, _>>(),
720 )
721 }
722}
723
724impl<V> DamlSerializeFrom<DamlTextMap<V>> for DamlValue
725where
726 V: DamlSerializableType + DamlSerializeInto<DamlValue>,
727{
728 fn serialize_from(text_map: DamlTextMap<V>) -> DamlValue {
729 DamlValue::new_map(text_map.0.into_iter().map(|(k, v)| (k, V::serialize_into(v))).collect::<DamlTextMap<_>>())
730 }
731}
732
733impl DamlDeserializeFrom for DamlUnit {
734 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
735 match value {
736 DamlValue::Unit => Ok(()),
737 _ => Err(value.make_unexpected_type_error("Unit")),
738 }
739 }
740}
741
742impl DamlDeserializeFrom for DamlBool {
743 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
744 match value {
745 DamlValue::Bool(b) => Ok(b),
746 _ => Err(value.make_unexpected_type_error("Bool")),
747 }
748 }
749}
750
751impl DamlDeserializeFrom for DamlInt64 {
752 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
753 match value {
754 DamlValue::Int64(i) => Ok(i),
755 _ => Err(value.make_unexpected_type_error("Int64")),
756 }
757 }
758}
759
760impl DamlDeserializeFrom for DamlText {
761 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
762 match value {
763 DamlValue::Text(s) => Ok(s),
764 _ => Err(value.make_unexpected_type_error("Text")),
765 }
766 }
767}
768
769impl DamlDeserializeFrom for DamlParty {
770 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
771 match value {
772 DamlValue::Party(party) => Ok(party),
773 _ => Err(value.make_unexpected_type_error("Party")),
774 }
775 }
776}
777
778impl DamlDeserializeFrom for DamlContractId {
779 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
780 match value {
781 DamlValue::ContractId(contract_id) => Ok(contract_id),
782 _ => Err(value.make_unexpected_type_error("ContractId")),
783 }
784 }
785}
786
787impl<T> DamlDeserializeFrom for DamlFixedNumeric<T>
788where
789 T: DamlDeserializableType + Nat,
790{
791 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
792 match value {
793 DamlValue::Numeric(numeric) => Ok(DamlFixedNumeric::new(numeric)),
794 _ => Err(value.make_unexpected_type_error("Numeric")),
795 }
796 }
797}
798
799impl DamlDeserializeFrom for DamlTimestamp {
800 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
801 match value {
802 DamlValue::Timestamp(timestamp) => Ok(timestamp),
803 _ => Err(value.make_unexpected_type_error("Timestamp")),
804 }
805 }
806}
807
808impl DamlDeserializeFrom for DamlDate {
809 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
810 match value {
811 DamlValue::Date(date) => Ok(date),
812 _ => Err(value.make_unexpected_type_error("Date")),
813 }
814 }
815}
816
817impl<T> DamlDeserializeFrom for Box<T>
818where
819 T: DamlDeserializeFrom + DamlDeserializableType,
820{
821 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
822 Ok(Box::new(value.deserialize_into()?))
823 }
824}
825
826impl<T> DamlDeserializeFrom for DamlOptional<T>
827where
828 T: DamlDeserializeFrom + DamlDeserializableType,
829{
830 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
831 match value {
832 DamlValue::Optional(o) => Ok(o.map(|a| T::deserialize_from(*a)).transpose()?),
833 _ => Err(value.make_unexpected_type_error("Option")),
834 }
835 }
836}
837
838impl<T> DamlDeserializeFrom for DamlList<T>
839where
840 T: DamlDeserializeFrom + DamlDeserializableType,
841{
842 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
843 match value {
844 DamlValue::List(l) => Ok(l.into_iter().map(T::deserialize_from).collect::<DamlResult<DamlList<_>>>()?),
845 _ => Err(value.make_unexpected_type_error("List")),
846 }
847 }
848}
849
850impl<V> DamlDeserializeFrom for DamlTextMap<V>
851where
852 V: DamlDeserializeFrom + DamlDeserializableType,
853{
854 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
855 match value {
856 DamlValue::Map(text_map) => Ok(text_map
857 .into_iter()
858 .map(|(k, v)| Ok((k, V::deserialize_from(v)?)))
859 .collect::<DamlResult<DamlTextMap<_>>>()?),
860 _ => Err(value.make_unexpected_type_error("Map")),
861 }
862 }
863}
864
865impl<K, V> DamlDeserializeFrom for DamlGenMap<K, V>
866where
867 K: DamlDeserializeFrom + DamlDeserializableType + Ord,
868 V: DamlDeserializeFrom + DamlDeserializableType,
869{
870 fn deserialize_from(value: DamlValue) -> DamlResult<Self> {
871 match value {
872 DamlValue::GenMap(gen_map) => Ok(gen_map
873 .into_iter()
874 .map(|(k, v)| Ok((K::deserialize_from(k)?, V::deserialize_from(v)?)))
875 .collect::<DamlResult<DamlGenMap<_, _>>>()?),
876 _ => Err(value.make_unexpected_type_error("GenMap")),
877 }
878 }
879}
880
881impl TryFrom<Value> for DamlValue {
882 type Error = DamlError;
883
884 fn try_from(value: Value) -> Result<Self, Self::Error> {
885 Ok(match value.sum.req()? {
886 Sum::Record(v) => DamlValue::Record(v.try_into()?),
887 Sum::Variant(v) => DamlValue::Variant((*v).try_into()?),
888 Sum::Enum(e) => DamlValue::Enum(e.into()),
889 Sum::ContractId(v) => DamlValue::ContractId(DamlContractId::new(v)),
890 Sum::List(v) =>
891 DamlValue::List(v.elements.into_iter().map(TryInto::try_into).collect::<DamlResult<DamlList<_>>>()?),
892 Sum::Int64(v) => DamlValue::Int64(v),
893 Sum::Numeric(v) => DamlValue::Numeric(DamlNumeric::from_str(&v)?),
894 Sum::Text(v) => DamlValue::Text(v),
895 Sum::Timestamp(v) => DamlValue::Timestamp(util::datetime_from_micros(v)?),
896 Sum::Party(v) => DamlValue::Party(DamlParty::new(v)),
897 Sum::Bool(v) => DamlValue::Bool(v),
898 Sum::Unit(_) => DamlValue::Unit,
899 Sum::Date(v) => DamlValue::Date(util::date_from_days(v)?),
900 Sum::Optional(v) =>
901 DamlValue::Optional(v.value.map(|v| DamlValue::try_from(*v)).transpose()?.map(Box::new)),
902 Sum::Map(v) => DamlValue::Map(
903 v.entries
904 .into_iter()
905 .map(|v| Ok((v.key, v.value.req().and_then(DamlValue::try_from)?)))
906 .collect::<DamlResult<DamlTextMap<_>>>()?,
907 ),
908 Sum::GenMap(v) => DamlValue::GenMap(
909 v.entries
910 .into_iter()
911 .map(|v| {
912 Ok((v.key.req().and_then(DamlValue::try_from)?, v.value.req().and_then(DamlValue::try_from)?))
913 })
914 .collect::<DamlResult<DamlGenMap<_, _>>>()?,
915 ),
916 })
917 }
918}
919
920impl From<DamlValue> for Value {
921 fn from(daml_value: DamlValue) -> Self {
922 Self {
923 sum: match daml_value {
924 DamlValue::Record(v) => Some(Sum::Record(Record::from(v))),
925 DamlValue::Variant(v) => Some(Sum::Variant(Box::new(Variant::from(v)))),
926 DamlValue::Enum(e) => Some(Sum::Enum(Enum::from(e))),
927 DamlValue::ContractId(v) => Some(Sum::ContractId(v.contract_id)),
928 DamlValue::List(v) => Some(Sum::List(List {
929 elements: v.into_iter().map(Value::from).collect(),
930 })),
931 DamlValue::Int64(v) => Some(Sum::Int64(v)),
932 DamlValue::Numeric(v) => Some(Sum::Numeric(format!("{:.37}", v))),
934 DamlValue::Text(v) => Some(Sum::Text(v)), DamlValue::Timestamp(v) => Some(Sum::Timestamp(v.timestamp())),
936 DamlValue::Party(v) => Some(Sum::Party(v.party)),
937 DamlValue::Bool(v) => Some(Sum::Bool(v)),
938 DamlValue::Unit => Some(Sum::Unit(())),
939 DamlValue::Date(v) => Some(Sum::Date(util::days_from_date(v))),
940 DamlValue::Optional(Some(v)) => Some(Sum::Optional(Box::new(Optional {
941 value: Some(Box::new(Value::from(*v))),
942 }))),
943 DamlValue::Optional(None) => Some(Sum::Optional(Box::new(Optional {
944 value: None,
945 }))),
946 DamlValue::Map(v) => Some(Sum::Map(Map {
947 entries: v
948 .into_iter()
949 .map(|(key, val)| map::Entry {
950 key,
951 value: Some(val.into()),
952 })
953 .collect(),
954 })),
955 DamlValue::GenMap(v) => Some(Sum::GenMap(GenMap {
956 entries: v
957 .into_iter()
958 .map(|(key, val)| gen_map::Entry {
959 key: Some(key.into()),
960 value: Some(val.into()),
961 })
962 .collect(),
963 })),
964 },
965 }
966 }
967}
968
969impl PartialOrd for DamlValue {
973 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
974 match (self, other) {
975 (DamlValue::Record(v1), DamlValue::Record(v2)) => v1.partial_cmp(v2),
976 (DamlValue::Variant(v1), DamlValue::Variant(v2)) => v1.partial_cmp(v2),
977 (DamlValue::Enum(v1), DamlValue::Enum(v2)) => v1.partial_cmp(v2),
978 (DamlValue::List(v1), DamlValue::List(v2)) => v1.partial_cmp(v2.as_ref()),
979 (DamlValue::Int64(v1), DamlValue::Int64(v2)) => v1.partial_cmp(v2),
980 (DamlValue::Numeric(v1), DamlValue::Numeric(v2)) => v1.partial_cmp(v2),
981 (DamlValue::Text(v1), DamlValue::Text(v2)) => v1.partial_cmp(v2),
982 (DamlValue::Party(v1), DamlValue::Party(v2)) => v1.party.partial_cmp(&v2.party),
983 (DamlValue::ContractId(v1), DamlValue::ContractId(v2)) => v1.contract_id.partial_cmp(&v2.contract_id),
984 (DamlValue::Timestamp(v1), DamlValue::Timestamp(v2)) => v1.partial_cmp(v2),
985 (DamlValue::Bool(v1), DamlValue::Bool(v2)) => v1.partial_cmp(v2),
986 (DamlValue::Unit, DamlValue::Unit) => Some(Ordering::Equal),
987 (DamlValue::Date(v1), DamlValue::Date(v2)) => v1.partial_cmp(v2),
988 (DamlValue::Optional(v1), DamlValue::Optional(v2)) => v1.partial_cmp(v2),
989 (DamlValue::Map(v1), DamlValue::Map(v2)) =>
990 if v1.len() == v2.len() {
991 v1.keys().sorted().partial_cmp(v2.keys().sorted())
992 } else {
993 v1.len().partial_cmp(&v2.len())
994 },
995 (DamlValue::GenMap(v1), DamlValue::GenMap(v2)) =>
996 if v1.len() == v2.len() {
997 v1.keys().partial_cmp(v2.keys())
998 } else {
999 v1.len().partial_cmp(&v2.len())
1000 },
1001 _ => None,
1002 }
1003 }
1004}
1005
1006impl Ord for DamlValue {
1007 fn cmp(&self, other: &Self) -> Ordering {
1008 self.partial_cmp(other).unwrap()
1009 }
1010}
1011
1012#[cfg(test)]
1013mod tests {
1014 use crate::data::value::DamlValue;
1015 use crate::primitive_types::{DamlGenMap, DamlTextMap};
1016 use std::cmp::Ordering;
1017
1018 #[test]
1019 fn test_eq_for_text() {
1020 let value1 = DamlValue::Text(String::from("text"));
1021 let value2 = DamlValue::Text(String::from("text"));
1022 assert_eq!(value1, value2);
1023 }
1024
1025 #[test]
1026 fn test_ord_for_text() {
1027 let value1 = DamlValue::Text(String::from("textA"));
1028 let value2 = DamlValue::Text(String::from("textB"));
1029 assert_eq!(value1.cmp(&value2), Ordering::Less);
1030 }
1031
1032 #[test]
1033 fn test_eq_for_i64() {
1034 let value1 = DamlValue::Int64(101);
1035 let value2 = DamlValue::Int64(101);
1036 assert_eq!(value1, value2);
1037 }
1038
1039 #[test]
1040 fn test_ord_for_i64() {
1041 let value1 = DamlValue::Int64(102);
1042 let value2 = DamlValue::Int64(101);
1043 assert_eq!(value1.cmp(&value2), Ordering::Greater);
1044 }
1045
1046 #[test]
1047 fn test_eq_for_textmap() {
1048 let items =
1049 vec![(String::from("text1"), DamlValue::Int64(100)), (String::from("text2"), DamlValue::Int64(200))];
1050 let value1 = DamlValue::Map(items.clone().into_iter().collect::<DamlTextMap<DamlValue>>());
1051 let value2 = DamlValue::Map(items.into_iter().collect::<DamlTextMap<DamlValue>>());
1052 assert_eq!(value1, value2);
1053 }
1054
1055 #[test]
1056 fn test_ord_for_textmap() {
1057 let items1 =
1058 vec![(String::from("text1"), DamlValue::Int64(100)), (String::from("text2"), DamlValue::Int64(200))];
1059 let items2 =
1060 vec![(String::from("text2"), DamlValue::Int64(100)), (String::from("text3"), DamlValue::Int64(200))];
1061 let items3 =
1062 vec![(String::from("text1"), DamlValue::Int64(100)), (String::from("text2"), DamlValue::Int64(200))];
1063 let value1 = DamlValue::Map(items1.into_iter().collect::<DamlTextMap<DamlValue>>());
1064 let value2 = DamlValue::Map(items2.into_iter().collect::<DamlTextMap<DamlValue>>());
1065 let value3 = DamlValue::Map(items3.into_iter().collect::<DamlTextMap<DamlValue>>());
1066 assert_eq!(value1.cmp(&value2), Ordering::Less);
1067 assert_eq!(value2.cmp(&value1), Ordering::Greater);
1068 assert_eq!(value1.cmp(&value3), Ordering::Equal);
1069 }
1070
1071 #[test]
1072 fn test_eq_for_genmap() {
1073 let items = vec![
1074 (DamlValue::Text(String::from("text1")), DamlValue::Int64(100)),
1075 (DamlValue::Text(String::from("text2")), DamlValue::Int64(200)),
1076 ];
1077 let value1 = DamlValue::GenMap(items.clone().into_iter().collect::<DamlGenMap<_, _>>());
1078 let value2 = DamlValue::GenMap(items.into_iter().collect::<DamlGenMap<_, _>>());
1079 assert_eq!(value1, value2);
1080 }
1081
1082 #[test]
1083 fn test_ord_for_genmap() {
1084 let items1 = vec![
1085 (DamlValue::Text(String::from("text1")), DamlValue::Int64(100)),
1086 (DamlValue::Text(String::from("text2")), DamlValue::Int64(200)),
1087 ];
1088 let items2 = vec![
1089 (DamlValue::Text(String::from("text2")), DamlValue::Int64(100)),
1090 (DamlValue::Text(String::from("text3")), DamlValue::Int64(200)),
1091 ];
1092 let items3 = vec![
1093 (DamlValue::Text(String::from("text1")), DamlValue::Int64(100)),
1094 (DamlValue::Text(String::from("text2")), DamlValue::Int64(200)),
1095 ];
1096 let value1 = DamlValue::GenMap(items1.into_iter().collect::<DamlGenMap<DamlValue, DamlValue>>());
1097 let value2 = DamlValue::GenMap(items2.into_iter().collect::<DamlGenMap<DamlValue, DamlValue>>());
1098 let value3 = DamlValue::GenMap(items3.into_iter().collect::<DamlGenMap<DamlValue, DamlValue>>());
1099 assert_eq!(value1.cmp(&value2), Ordering::Less);
1100 assert_eq!(value2.cmp(&value1), Ordering::Greater);
1101 assert_eq!(value1.cmp(&value3), Ordering::Equal);
1102 }
1103}