1use crate::error::{DamlJsonCodecError, DamlJsonCodecResult};
2use crate::util::{AsSingleSliceExt, Required};
3use chrono::{offset, Date, DateTime, NaiveDate};
4use daml_grpc::data::value::{DamlEnum, DamlRecord, DamlRecordField, DamlValue, DamlVariant};
5use daml_grpc::data::DamlIdentifier;
6use daml_grpc::primitive_types::{DamlGenMap, DamlInt64, DamlNumeric, DamlTextMap};
7use daml_lf::element;
8use daml_lf::element::{DamlArchive, DamlData, DamlField, DamlType};
9use serde_json::{Map, Value};
10use std::convert::TryFrom;
11use std::str::FromStr;
12
13#[derive(Debug)]
15pub struct JsonValueDecoder<'a> {
16 arc: &'a DamlArchive<'a>,
17}
18
19impl<'a> JsonValueDecoder<'a> {
20 pub const fn new(arc: &'a DamlArchive<'a>) -> Self {
21 Self {
22 arc,
23 }
24 }
25
26 pub fn decode(&self, json: &Value, ty: &DamlType<'_>) -> DamlJsonCodecResult<DamlValue> {
33 self.do_decode(json, ty, true)
34 }
35
36 fn do_decode(&self, json: &Value, ty: &DamlType<'_>, top_level: bool) -> DamlJsonCodecResult<DamlValue> {
41 match ty {
42 DamlType::Unit =>
43 if json.try_object()?.is_empty() {
44 Ok(DamlValue::Unit)
45 } else {
46 Err(DamlJsonCodecError::UnexpectedUnitData)
47 },
48 DamlType::Bool => Self::decode_bool(json),
49 DamlType::Int64 => Self::decode_int64(json),
50 DamlType::Text => Self::decode_text(json),
51 DamlType::Party => Self::decode_party(json),
52 DamlType::ContractId(_) => Self::decode_contract_id(json),
53 DamlType::Numeric(_) => Self::decode_numeric(json),
54 DamlType::Date => Self::decode_date(json),
55 DamlType::Timestamp => Self::decode_timestamp(json),
56 DamlType::List(tys) => Ok(DamlValue::List(
57 json.try_array()?
58 .iter()
59 .map(|item| self.do_decode(item, tys.as_single()?, true))
60 .collect::<DamlJsonCodecResult<Vec<_>>>()?,
61 )),
62 DamlType::TextMap(tys) => Ok(DamlValue::Map(
63 json.try_object()?
64 .iter()
65 .map(|(k, v)| Ok((k.clone(), self.do_decode(v, tys.as_single()?, true)?)))
66 .collect::<DamlJsonCodecResult<DamlTextMap<DamlValue>>>()?,
67 )),
68 DamlType::GenMap(tys) => {
69 let array = json.try_array()?;
70 let genmap = array
71 .iter()
72 .map(|item| match item.try_array()?.as_slice() {
73 [k, v] => Ok((
74 self.do_decode(k, tys.first().req()?, true)?,
75 self.do_decode(v, tys.last().req()?, true)?,
76 )),
77 _ => Err(DamlJsonCodecError::UnexpectedGenMapTypes),
78 })
79 .collect::<DamlJsonCodecResult<DamlGenMap<DamlValue, DamlValue>>>()?;
80
81 if array.len() == genmap.len() {
84 Ok(DamlValue::GenMap(genmap))
85 } else {
86 Err(DamlJsonCodecError::DuplicateGenMapKeys)
87 }
88 },
89 DamlType::TyCon(tycon) | DamlType::BoxedTyCon(tycon) => self.decode_data(
90 json,
91 self.arc
92 .data_by_tycon(tycon)
93 .ok_or_else(|| DamlJsonCodecError::DataNotFound(tycon.tycon().to_string()))?,
94 ),
95 DamlType::Optional(nested) => {
96 let single = nested.as_single()?;
97 if top_level {
98 if json.is_null() {
99 Ok(DamlValue::Optional(None))
100 } else {
101 Ok(DamlValue::Optional(Some(Box::new(self.do_decode(json, single, false)?))))
102 }
103 } else {
104 match json.try_array()?.as_slice() {
105 [] => Ok(DamlValue::Optional(None)),
106 [inner_json] =>
107 Ok(DamlValue::Optional(Some(Box::new(self.do_decode(inner_json, single, false)?)))),
108 _ => Err(DamlJsonCodecError::UnexpectedOptionalArrayLength),
109 }
110 }
111 },
112 DamlType::Var(_)
113 | DamlType::Nat(_)
114 | DamlType::Arrow
115 | DamlType::Any
116 | DamlType::TypeRep
117 | DamlType::Bignumeric
118 | DamlType::RoundingMode
119 | DamlType::AnyException
120 | DamlType::Update
121 | DamlType::Scenario
122 | DamlType::Forall(_)
123 | DamlType::Struct(_)
124 | DamlType::Syn(_) => Err(DamlJsonCodecError::UnsupportedDamlType(ty.name().to_owned())),
125 }
126 }
127
128 fn decode_bool(json: &Value) -> DamlJsonCodecResult<DamlValue> {
129 Ok(DamlValue::Bool(json.try_bool()?))
130 }
131
132 fn decode_int64(json: &Value) -> DamlJsonCodecResult<DamlValue> {
133 match (json.as_i64(), json.as_str()) {
134 (Some(i64), None) => Ok(DamlValue::new_int64(i64)),
135 (None, Some(s)) => Ok(DamlValue::new_int64(DamlInt64::from_str(s)?)),
136 _ => Err(DamlJsonCodecError::UnexpectedJsonType(
137 "i64 or String".to_owned(),
138 Value::json_value_name(json).to_owned(),
139 )),
140 }
141 }
142
143 fn decode_numeric(json: &Value) -> DamlJsonCodecResult<DamlValue> {
144 match (json.as_f64(), json.as_str()) {
145 (Some(f64), None) => Ok(DamlValue::new_numeric(DamlNumeric::try_from(f64)?)),
146 (None, Some(s)) => Ok(DamlValue::new_numeric(DamlNumeric::from_str(s)?)),
147 _ => Err(DamlJsonCodecError::UnexpectedJsonType(
148 "f64 or String".to_owned(),
149 Value::json_value_name(json).to_owned(),
150 )),
151 }
152 }
153
154 fn decode_date(json: &Value) -> DamlJsonCodecResult<DamlValue> {
155 Ok(DamlValue::new_date(Date::from_utc(NaiveDate::parse_from_str(json.try_string()?, "%Y-%m-%d")?, offset::Utc)))
156 }
157
158 fn decode_timestamp(json: &Value) -> DamlJsonCodecResult<DamlValue> {
159 Ok(DamlValue::new_timestamp(DateTime::parse_from_rfc3339(json.try_string()?)?))
160 }
161
162 fn decode_text(json: &Value) -> DamlJsonCodecResult<DamlValue> {
163 Ok(DamlValue::new_text(json.try_string()?))
164 }
165
166 fn decode_party(json: &Value) -> DamlJsonCodecResult<DamlValue> {
167 Ok(DamlValue::new_party(json.try_string()?))
168 }
169
170 fn decode_contract_id(json: &Value) -> DamlJsonCodecResult<DamlValue> {
171 Ok(DamlValue::new_contract_id(json.try_string()?))
172 }
173
174 fn decode_data(&self, json: &Value, data: &DamlData<'_>) -> DamlJsonCodecResult<DamlValue> {
176 match data {
177 DamlData::Template(template) => self.decode_record(json, template.fields()),
178 DamlData::Record(record) => self.decode_record(json, record.fields()),
179 DamlData::Variant(variant) => self.decode_variant(json, variant.fields()),
180 DamlData::Enum(data_enum) => Self::decode_enum(json, data_enum),
181 }
182 }
183
184 fn decode_enum(json: &Value, data_enum: &element::DamlEnum<'_>) -> DamlJsonCodecResult<DamlValue> {
186 let constructor = json.try_string()?;
187 if data_enum.constructors().any(|c| c == constructor) {
188 Ok(DamlValue::Enum(DamlEnum::new(constructor, None::<DamlIdentifier>)))
189 } else {
190 Err(DamlJsonCodecError::UnknownEnumConstructor(constructor.to_owned()))
191 }
192 }
193
194 fn decode_variant(&self, json: &Value, constructors: &[DamlField<'_>]) -> DamlJsonCodecResult<DamlValue> {
196 let object = json.try_object()?;
197 let tag = object.get("tag").req()?.try_string()?;
198 let value = object.get("value").req()?;
199 let constructor = constructors
200 .iter()
201 .find(|&field| field.name() == tag)
202 .ok_or_else(|| DamlJsonCodecError::UnknownVariantConstructor(tag.to_owned()))?;
203 Ok(DamlValue::Variant(DamlVariant::new(
204 constructor.name(),
205 Box::new(self.decode(value, constructor.ty())?),
206 None::<DamlIdentifier>,
207 )))
208 }
209
210 fn decode_record(&self, json: &Value, lf_fields: &[DamlField<'_>]) -> DamlJsonCodecResult<DamlValue> {
212 let fields = match (json.as_object(), json.as_array()) {
213 (Some(obj), None) => self.decode_record_object(obj, lf_fields)?,
214 (None, Some(arr)) => self.decode_record_array(arr, lf_fields)?,
215 _ =>
216 return Err(DamlJsonCodecError::UnexpectedJsonType(
217 "Object or Array".to_owned(),
218 Value::json_value_name(json).to_owned(),
219 )),
220 };
221 Ok(DamlValue::Record(DamlRecord::new(fields, None::<DamlIdentifier>)))
222 }
223
224 fn decode_record_object(
225 &self,
226 obj: &Map<String, Value>,
227 lf_fields: &[DamlField<'_>],
228 ) -> DamlJsonCodecResult<Vec<DamlRecordField>> {
229 lf_fields
230 .iter()
231 .map(|field| {
232 let field_name = field.name();
233 let field_ty = field.ty();
234 let field_json = obj.get(field_name);
235 match (field_ty, field_json) {
236 (DamlType::Optional(_), None) =>
237 Ok(DamlRecordField::new(Some(field_name), DamlValue::Optional(None))),
238 (_, Some(json)) => Ok(DamlRecordField::new(Some(field_name), self.decode(json, field_ty)?)),
239 (_, None) => Err(DamlJsonCodecError::MissingJsonRecordObjectField(field_name.to_owned())),
240 }
241 })
242 .collect::<DamlJsonCodecResult<Vec<DamlRecordField>>>()
243 }
244
245 fn decode_record_array(
246 &self,
247 arr: &[Value],
248 lf_fields: &[DamlField<'_>],
249 ) -> DamlJsonCodecResult<Vec<DamlRecordField>> {
250 lf_fields
251 .iter()
252 .enumerate()
253 .map(|(i, field)| {
254 let json = arr
255 .get(i)
256 .ok_or_else(|| DamlJsonCodecError::MissingJsonRecordArrayField(i, field.name().to_owned()))?;
257 Ok(DamlRecordField::new(Some(field.name()), self.decode(json, field.ty())?))
258 })
259 .collect::<DamlJsonCodecResult<Vec<DamlRecordField>>>()
260 }
261}
262
263pub trait JsonTryAsExt {
265 fn try_null(&self) -> DamlJsonCodecResult<()>;
266 fn try_bool(&self) -> DamlJsonCodecResult<bool>;
267 fn try_int64(&self) -> DamlJsonCodecResult<i64>;
268 fn try_string(&self) -> DamlJsonCodecResult<&str>;
269 fn try_array(&self) -> DamlJsonCodecResult<&Vec<Value>>;
270 fn try_object(&self) -> DamlJsonCodecResult<&Map<String, Value>>;
271 fn make_unexpected_type_error(value: &Value, expected: &str) -> DamlJsonCodecError {
272 DamlJsonCodecError::UnexpectedJsonType(expected.to_owned(), Self::json_value_name(value).to_owned())
273 }
274 fn json_value_name(value: &Value) -> &str {
275 match value {
276 Value::Null => "Null",
277 Value::Bool(_) => "Bool",
278 Value::Number(_) => "Number",
279 Value::String(_) => "String",
280 Value::Array(_) => "Array",
281 Value::Object(_) => "Object",
282 }
283 }
284}
285
286impl JsonTryAsExt for Value {
287 fn try_null(&self) -> DamlJsonCodecResult<()> {
288 self.as_null().ok_or_else(|| Self::make_unexpected_type_error(self, "Null"))
289 }
290
291 fn try_bool(&self) -> DamlJsonCodecResult<bool> {
292 self.as_bool().ok_or_else(|| Self::make_unexpected_type_error(self, "Bool"))
293 }
294
295 fn try_int64(&self) -> DamlJsonCodecResult<i64> {
296 self.as_i64().ok_or_else(|| Self::make_unexpected_type_error(self, "Number(i64)"))
297 }
298
299 fn try_string(&self) -> DamlJsonCodecResult<&str> {
300 self.as_str().ok_or_else(|| Self::make_unexpected_type_error(self, "String"))
301 }
302
303 fn try_array(&self) -> DamlJsonCodecResult<&Vec<Value>> {
304 self.as_array().ok_or_else(|| Self::make_unexpected_type_error(self, "Array"))
305 }
306
307 fn try_object(&self) -> DamlJsonCodecResult<&Map<String, Value>> {
308 self.as_object().ok_or_else(|| Self::make_unexpected_type_error(self, "Object"))
309 }
310}
311
312#[cfg(test)]
313mod tests {
314 use super::{
315 DamlArchive, DamlEnum, DamlJsonCodecError, DamlJsonCodecResult, DamlType, DamlValue, JsonValueDecoder, Value,
316 };
317 use daml::macros::daml_value;
318 use daml_grpc::primitive_types::DamlTextMap;
319 use daml_lf::DarFile;
320 use maplit::hashmap;
321 use serde_json::json;
322
323 static TESTING_TYPES_DAR_PATH: &str = "../resources/testing_types_sandbox/TestingTypes-latest.dar";
324
325 #[test]
327 fn test_unit() -> DamlJsonCodecResult<()> {
328 let json_value = json!({});
329 let ty = DamlType::Unit;
330 let expected = daml_value!();
331 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
332 assert_eq!(actual, expected);
333 Ok(())
334 }
335
336 #[test]
338 fn test_bool() -> DamlJsonCodecResult<()> {
339 let json_value = json!(true);
340 let ty = DamlType::Bool;
341 let expected = daml_value!(true);
342 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
343 assert_eq!(actual, expected);
344 Ok(())
345 }
346
347 #[test]
349 fn test_int64() -> DamlJsonCodecResult<()> {
350 let json_value = json!(42);
351 let ty = DamlType::Int64;
352 let expected = daml_value!(42);
353 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
354 assert_eq!(actual, expected);
355 Ok(())
356 }
357
358 #[test]
360 fn test_int64_neg() -> DamlJsonCodecResult<()> {
361 let json_value = json!(-42);
362 let ty = DamlType::Int64;
363 let expected = daml_value!(-42);
364 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
365 assert_eq!(actual, expected);
366 Ok(())
367 }
368
369 #[test]
371 fn test_int64_string() -> DamlJsonCodecResult<()> {
372 let json_value = json!("42");
373 let ty = DamlType::Int64;
374 let expected = daml_value!(42);
375 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
376 assert_eq!(actual, expected);
377 Ok(())
378 }
379
380 #[test]
382 fn test_int64_neg_string() -> DamlJsonCodecResult<()> {
383 let json_value = json!("-42");
384 let ty = DamlType::Int64;
385 let expected = daml_value!(-42);
386 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
387 assert_eq!(actual, expected);
388 Ok(())
389 }
390
391 #[test]
393 fn test_int64_fails() {
394 let json_value = json!(4.2);
395 let ty = DamlType::Int64;
396 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
397 assert!(actual.is_err());
398 }
399
400 #[test]
402 fn test_numeric_f64() -> DamlJsonCodecResult<()> {
403 let json_value = json!(1.0);
404 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
405 let expected = daml_value!(1.0);
406 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
407 assert_eq!(actual, expected);
408 Ok(())
409 }
410
411 #[test]
413 fn test_numeric_f64_neg() -> DamlJsonCodecResult<()> {
414 let json_value = json!(-1.0);
415 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
416 let expected = daml_value!(-1.0);
417 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
418 assert_eq!(actual, expected);
419 Ok(())
420 }
421
422 #[test]
424 fn test_numeric_string() -> DamlJsonCodecResult<()> {
425 let json_value = json!("1.23");
426 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
427 let expected = daml_value!(1.23);
428 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
429 assert_eq!(actual, expected);
430 Ok(())
431 }
432
433 #[test]
435 fn test_numeric_string_neg() -> DamlJsonCodecResult<()> {
436 let json_value = json!("-1.23");
437 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
438 let expected = daml_value!(-1.23);
439 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
440 assert_eq!(actual, expected);
441 Ok(())
442 }
443
444 #[test]
446 #[allow(clippy::unreadable_literal)]
447 fn test_numeric_f64_round() -> DamlJsonCodecResult<()> {
448 let json_value = json!(0.30000000000000004);
449 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
450 let expected = daml_value!(0.3);
451 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
452 assert_eq!(actual, expected);
453 Ok(())
454 }
455
456 #[test]
458 fn test_numeric_f64_sci() -> DamlJsonCodecResult<()> {
459 let json_value = json!(2e3);
460 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
461 let expected = daml_value!(2000.0);
462 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
463 assert_eq!(actual, expected);
464 Ok(())
465 }
466
467 #[test]
469 fn test_numeric_f64_neg_zero() -> DamlJsonCodecResult<()> {
470 let json_value = json!(-0);
471 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
472 let expected = daml_value!(0.0);
473 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
474 assert_eq!(actual, expected);
475 Ok(())
476 }
477
478 #[test]
480 #[allow(clippy::unreadable_literal)]
481 fn test_numeric_f64_large() -> DamlJsonCodecResult<()> {
482 let json_value = json!(9999999999999999999999999999.9999999999);
483 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
484 let expected = daml_value!(9999999999999999999999999999.9999999999);
485 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
486 assert_eq!(actual, expected);
487 Ok(())
488 }
489
490 #[test]
492 fn test_numeric_f64_whole() -> DamlJsonCodecResult<()> {
493 let json_value = json!(42);
494 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
495 let expected = daml_value!(42.0);
496 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
497 assert_eq!(actual, expected);
498 Ok(())
499 }
500
501 #[test]
503 fn test_numeric_string_whole() -> DamlJsonCodecResult<()> {
504 let json_value = json!("42");
505 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
506 let expected = daml_value!(42.0);
507 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
508 assert_eq!(actual, expected);
509 Ok(())
510 }
511
512 #[test]
514 fn test_numeric_string_fails_garbage() {
515 let json_value = json!("blah");
516 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
517 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
518 assert!(actual.is_err());
519 }
520
521 #[test]
523 fn test_numeric_string_fails_whitespace() {
524 let json_value = json!(" 42 ");
525 let ty = DamlType::Numeric(vec![DamlType::Nat(10)]);
526 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
527 assert!(actual.is_err());
528 }
529
530 #[test]
532 fn test_text() -> DamlJsonCodecResult<()> {
533 let json_value = json!("test");
534 let ty = DamlType::Text;
535 let expected = daml_value!("test");
536 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
537 assert_eq!(actual, expected);
538 Ok(())
539 }
540
541 #[test]
543 fn test_text_empty() -> DamlJsonCodecResult<()> {
544 let json_value = json!("");
545 let ty = DamlType::Text;
546 let expected = daml_value!("");
547 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
548 assert_eq!(actual, expected);
549 Ok(())
550 }
551
552 #[test]
554 fn test_date() -> DamlJsonCodecResult<()> {
555 let json_value = json!("2019-06-18");
556 let ty = DamlType::Date;
557 let expected = daml_value!("2019-06-18"::d);
558 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
559 assert_eq!(actual, expected);
560 Ok(())
561 }
562
563 #[test]
565 fn test_date_min() -> DamlJsonCodecResult<()> {
566 let json_value = json!("9999-12-31");
567 let ty = DamlType::Date;
568 let expected = daml_value!("9999-12-31"::d);
569 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
570 assert_eq!(actual, expected);
571 Ok(())
572 }
573
574 #[test]
576 fn test_date_max() -> DamlJsonCodecResult<()> {
577 let json_value = json!("0001-01-01");
578 let ty = DamlType::Date;
579 let expected = daml_value!("0001-01-01"::d);
580 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
581 assert_eq!(actual, expected);
582 Ok(())
583 }
584
585 #[test]
587 fn test_date_invalid_fails() {
588 let json_value = json!("9999-99-99");
589 let ty = DamlType::Date;
590 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
591 assert!(actual.is_err());
592 }
593
594 #[test]
596 fn test_timestamp_full() -> DamlJsonCodecResult<()> {
597 let json_value = json!("1990-11-09T04:30:23.1234569Z");
598 let ty = DamlType::Timestamp;
599 let expected = daml_value!("1990-11-09T04:30:23.1234569Z"::t);
600 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
601 assert_eq!(actual, expected);
602 Ok(())
603 }
604
605 #[test]
607 fn test_timestamp_no_sub_sec() -> DamlJsonCodecResult<()> {
608 let json_value = json!("1990-11-09T04:30:23Z");
609 let ty = DamlType::Timestamp;
610 let expected = daml_value!("1990-11-09T04:30:23Z"::t);
611 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
612 assert_eq!(actual, expected);
613 Ok(())
614 }
615
616 #[test]
618 fn test_timestamp_no_micros() -> DamlJsonCodecResult<()> {
619 let json_value = json!("1990-11-09T04:30:23.123Z");
620 let ty = DamlType::Timestamp;
621 let expected = daml_value!("1990-11-09T04:30:23.123Z"::t);
622 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
623 assert_eq!(actual, expected);
624 Ok(())
625 }
626
627 #[test]
629 fn test_timestamp_min() -> DamlJsonCodecResult<()> {
630 let json_value = json!("0001-01-01T00:00:00Z");
631 let ty = DamlType::Timestamp;
632 let expected = daml_value!("0001-01-01T00:00:00Z"::t);
633 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
634 assert_eq!(actual, expected);
635 Ok(())
636 }
637
638 #[test]
640 fn test_timestamp_max() -> DamlJsonCodecResult<()> {
641 let json_value = json!("9999-12-31T23:59:59.999999Z");
642 let ty = DamlType::Timestamp;
643 let expected = daml_value!("9999-12-31T23:59:59.999999Z"::t);
644 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
645 assert_eq!(actual, expected);
646 Ok(())
647 }
648
649 #[test]
651 fn test_party() -> DamlJsonCodecResult<()> {
652 let json_value = json!("Alice");
653 let ty = DamlType::Party;
654 let expected = daml_value!("Alice"::p);
655 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
656 assert_eq!(actual, expected);
657 Ok(())
658 }
659
660 #[test]
662 fn test_contract_id() -> DamlJsonCodecResult<()> {
663 let json_value = json!("foo:bar#baz");
664 let ty = DamlType::ContractId(None);
665 let expected = daml_value!("foo:bar#baz"::c);
666 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
667 assert_eq!(actual, expected);
668 Ok(())
669 }
670
671 #[test]
673 fn test_opt_int_null() -> DamlJsonCodecResult<()> {
674 let json_value = json!(null);
675 let ty = DamlType::Optional(vec![DamlType::Int64]);
676 let expected = daml_value!({?!});
677 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
678 assert_eq!(actual, expected);
679 Ok(())
680 }
681
682 #[test]
684 fn test_opt_int_null_fails() {
685 let json_value = json!([]);
686 let ty = DamlType::Optional(vec![DamlType::Int64]);
687 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
688 assert!(actual.is_err());
689 }
690
691 #[test]
693 fn test_opt_opt_int_some_should_fail() {
694 let json_value = json!([null]);
695 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])]);
696 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
697 assert!(actual.is_err());
698 }
699
700 #[test]
702 fn test_opt_opt_int_null() -> DamlJsonCodecResult<()> {
703 let json_value = json!(null);
704 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])]);
705 let expected = daml_value!({?!});
706 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
707 assert_eq!(actual, expected);
708 Ok(())
709 }
710
711 #[test]
713 fn test_opt_int_some() -> DamlJsonCodecResult<()> {
714 let json_value = json!(42);
715 let ty = DamlType::Optional(vec![DamlType::Int64]);
716 let expected = daml_value!({?=42});
717 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
718 assert_eq!(actual, expected);
719 Ok(())
720 }
721
722 #[test]
724 fn test_opt_opt_int_some_none() -> DamlJsonCodecResult<()> {
725 let json_value = json!([]);
726 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])]);
727 let expected = daml_value!({?={?!}});
728 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
729 assert_eq!(actual, expected);
730 Ok(())
731 }
732
733 #[test]
735 fn test_opt_opt_int_some_some() -> DamlJsonCodecResult<()> {
736 let json_value = json!([42]);
737 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])]);
738 let expected = daml_value!({?={?=42}});
739 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
740 assert_eq!(actual, expected);
741 Ok(())
742 }
743
744 #[test]
746 fn test_opt_opt_opt_int_some_some_none() -> DamlJsonCodecResult<()> {
747 let json_value = json!([[]]);
748 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])])]);
749 let expected = daml_value!({?={?={?!}}});
750 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
751 assert_eq!(actual, expected);
752 Ok(())
753 }
754
755 #[test]
757 fn test_opt_opt_opt_int_some_some_some() -> DamlJsonCodecResult<()> {
758 let json_value = json!([[42]]);
759 let ty = DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Int64])])]);
760 let expected = daml_value!({?={?={?=42}}});
761 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
762 assert_eq!(actual, expected);
763 Ok(())
764 }
765
766 #[test]
768 fn test_opt_opt_opt_opt_int_some_some_some_none() -> DamlJsonCodecResult<()> {
769 let json_value = json!([[[]]]);
770 let ty =
771 DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![
772 DamlType::Int64,
773 ])])])]);
774 let expected = daml_value!({?={?={?={?!}}}});
775 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
776 assert_eq!(actual, expected);
777 Ok(())
778 }
779
780 #[test]
782 fn test_opt_opt_opt_opt_int_some_some_some_some() -> DamlJsonCodecResult<()> {
783 let json_value = json!([[[42]]]);
784 let ty =
785 DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![DamlType::Optional(vec![
786 DamlType::Int64,
787 ])])])]);
788 let expected = daml_value!({?={?={?={?=42}}}});
789 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
790 assert_eq!(actual, expected);
791 Ok(())
792 }
793
794 #[test]
796 fn test_opt_unit_null() -> DamlJsonCodecResult<()> {
797 let json_value = json!(null);
798 let ty = DamlType::Optional(vec![DamlType::Unit]);
799 let expected = daml_value!({?!});
800 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
801 assert_eq!(actual, expected);
802 Ok(())
803 }
804
805 #[test]
807 fn test_opt_unit_some() -> DamlJsonCodecResult<()> {
808 let json_value = json!({});
809 let ty = DamlType::Optional(vec![DamlType::Unit]);
810 let expected = daml_value!({?=()});
811 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
812 assert_eq!(actual, expected);
813 Ok(())
814 }
815
816 #[test]
818 fn test_record() -> DamlJsonCodecResult<()> {
819 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
820 let json_value = json!({
821 "landlord": "Alice",
822 "tenant": "Bob",
823 "terms": "test terms",
824 });
825 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "RentDemo"], "RentalAgreement");
826 let expected = daml_value!({landlord: "Alice"::p, tenant: "Bob"::p, terms: "test terms"});
827 let actual = decode_apply(&dar, &json_value, &ty)?;
828 assert_eq!(actual, expected);
829 Ok(())
830 }
831
832 #[test]
834 fn test_record_array() -> DamlJsonCodecResult<()> {
835 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
836 let json_value = json!(["Alice", "Bob", 0]);
837 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "PingPong"], "Ping");
838 let expected = daml_value!({sender: "Alice"::p, receiver: "Bob"::p, count: 0});
839 let actual = decode_apply(&dar, &json_value, &ty)?;
840 assert_eq!(actual, expected);
841 Ok(())
842 }
843
844 #[test]
846 fn test_record_depth1_omitted() -> DamlJsonCodecResult<()> {
847 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
848 let json_value = json!({});
849 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth1");
850 let expected = daml_value!({foo: {?!}});
851 let actual = decode_apply(&dar, &json_value, &ty)?;
852 assert_eq!(actual, expected);
853 Ok(())
854 }
855
856 #[test]
858 fn test_record_depth1_none() -> DamlJsonCodecResult<()> {
859 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
860 let json_value = json!({ "foo": null });
861 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth1");
862 let expected = daml_value!({foo: {?!}});
863 let actual = decode_apply(&dar, &json_value, &ty)?;
864 assert_eq!(actual, expected);
865 Ok(())
866 }
867
868 #[test]
870 fn test_record_depth1_some() -> DamlJsonCodecResult<()> {
871 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
872 let json_value = json!({ "foo": 42 });
873 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth1");
874 let expected = daml_value!({foo: {?=42}});
875 let actual = decode_apply(&dar, &json_value, &ty)?;
876 assert_eq!(actual, expected);
877 Ok(())
878 }
879
880 #[test]
882 fn test_record_depth2_omitted() -> DamlJsonCodecResult<()> {
883 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
884 let json_value = json!({});
885 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth2");
886 let expected = daml_value!({foo: {?!}});
887 let actual = decode_apply(&dar, &json_value, &ty)?;
888 assert_eq!(actual, expected);
889 Ok(())
890 }
891
892 #[test]
894 fn test_record_depth2_none() -> DamlJsonCodecResult<()> {
895 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
896 let json_value = json!({ "foo": null });
897 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth2");
898 let expected = daml_value!({foo: {?!}});
899 let actual = decode_apply(&dar, &json_value, &ty)?;
900 assert_eq!(actual, expected);
901 Ok(())
902 }
903
904 #[test]
906 fn test_record_depth2_some_none() -> DamlJsonCodecResult<()> {
907 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
908 let json_value = json!({ "foo": [] });
909 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth2");
910 let expected = daml_value!({foo: {?={?!}}});
911 let actual = decode_apply(&dar, &json_value, &ty)?;
912 assert_eq!(actual, expected);
913 Ok(())
914 }
915
916 #[test]
918 fn test_record_depth2_some_some() -> DamlJsonCodecResult<()> {
919 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
920 let json_value = json!({ "foo": [42] });
921 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Depth2");
922 let expected = daml_value!({foo: {?={?=42}}});
923 let actual = decode_apply(&dar, &json_value, &ty)?;
924 assert_eq!(actual, expected);
925 Ok(())
926 }
927
928 #[test]
930 fn test_list_bool_empty() -> DamlJsonCodecResult<()> {
931 let json_value = json!([]);
932 let ty = DamlType::List(vec![DamlType::Bool]);
933 let expected = daml_value!([]);
934 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
935 assert_eq!(actual, expected);
936 Ok(())
937 }
938
939 #[test]
941 fn test_list_text() -> DamlJsonCodecResult<()> {
942 let json_value = json!(["a", "b", "c"]);
943 let ty = DamlType::List(vec![DamlType::Text]);
944 let expected = daml_value!(["a", "b", "c"]);
945 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
946 assert_eq!(actual, expected);
947 Ok(())
948 }
949
950 #[test]
952 fn test_list_opt_text() -> DamlJsonCodecResult<()> {
953 let json_value = json!(["a", null, "c"]);
954 let ty = DamlType::List(vec![DamlType::Optional(vec![DamlType::Text])]);
955 let expected = daml_value!([{?="a"}, {?!}, {?="c"}]);
956 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
957 assert_eq!(actual, expected);
958 Ok(())
959 }
960
961 #[test]
963 fn test_list_opt_mixed_fails() {
964 let json_value = json!([42, null, "c"]);
965 let ty = DamlType::List(vec![DamlType::Optional(vec![DamlType::Text])]);
966 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
967 assert!(actual.is_err());
968 }
969
970 #[test]
972 fn test_list_record() -> DamlJsonCodecResult<()> {
973 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
974 let json_value = json!([{
975 "landlord": "Alice",
976 "tenant": "Bob",
977 "terms": "test terms",
978 },
979 {
980 "landlord": "John",
981 "tenant": "Paul",
982 "terms": "more test terms",
983 }]);
984 let ty = DamlType::List(vec![DamlType::make_tycon(&dar.main.hash, &["Fuji", "RentDemo"], "RentalAgreement")]);
985 let expected = daml_value!([{
986 landlord: "Alice"::p,
987 tenant: "Bob"::p,
988 terms: "test terms"
989 },
990 {
991 landlord: "John"::p,
992 tenant: "Paul"::p,
993 terms: "more test terms"
994 }]);
995 let actual = decode_apply(&dar, &json_value, &ty)?;
996 assert_eq!(actual, expected);
997 Ok(())
998 }
999
1000 #[test]
1002 fn test_textmap_int_empty() -> DamlJsonCodecResult<()> {
1003 let json_value = json!({});
1004 let ty = DamlType::TextMap(vec![DamlType::Int64]);
1005 let expected = DamlValue::Map(vec![].into_iter().collect());
1006 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1007 assert_eq!(actual, expected);
1008 Ok(())
1009 }
1010
1011 #[test]
1013 fn test_textmap_int() -> DamlJsonCodecResult<()> {
1014 let json_value = json!({"foo": 42, "bar": 43});
1015 let ty = DamlType::TextMap(vec![DamlType::Int64]);
1016 let expected = DamlValue::Map(
1017 vec![("foo".to_owned(), daml_value![42]), ("bar".to_owned(), daml_value![43])].into_iter().collect(),
1018 );
1019 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1020 assert_eq!(actual, expected);
1021 Ok(())
1022 }
1023
1024 #[test]
1026 fn test_list_textmap_int() -> DamlJsonCodecResult<()> {
1027 let json_value = json!([{"foo": 42}, {"bar": 43}]);
1028 let ty = DamlType::List(vec![DamlType::TextMap(vec![DamlType::Int64])]);
1029 let expected = daml_value![[
1030 (DamlValue::Map(DamlTextMap::from(hashmap! {"foo".to_owned() => daml_value![42]}))),
1031 (DamlValue::Map(DamlTextMap::from(hashmap! {"bar".to_owned() => daml_value![43]})))
1032 ]];
1033 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1034 assert_eq!(actual, expected);
1035 Ok(())
1036 }
1037
1038 #[test]
1040 fn test_textmap_list_int() -> DamlJsonCodecResult<()> {
1041 let json_value = json!({"foo": [1, 2, 3], "bar": [4, 5, 6]});
1042 let ty = DamlType::TextMap(vec![DamlType::List(vec![DamlType::Int64])]);
1043 let expected = DamlValue::Map(DamlTextMap::from(hashmap! {
1044 "foo".to_owned() => daml_value![[1, 2, 3]],
1045 "bar".to_owned() => daml_value![[4, 5, 6]]
1046 }));
1047 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1048 assert_eq!(actual, expected);
1049 Ok(())
1050 }
1051
1052 #[test]
1054 fn test_textmap_record() -> DamlJsonCodecResult<()> {
1055 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1056 let json_value = json!({
1057 "first": {
1058 "landlord": "Alice",
1059 "tenant": "Bob",
1060 "terms": "test terms",
1061 },
1062 "last": {
1063 "landlord": "John",
1064 "tenant": "Paul",
1065 "terms": "more test terms",
1066 }});
1067 let ty =
1068 DamlType::TextMap(vec![DamlType::make_tycon(&dar.main.hash, &["Fuji", "RentDemo"], "RentalAgreement")]);
1069 let expected = DamlValue::Map(DamlTextMap::from(hashmap! {
1070 "first".to_owned() => daml_value!({landlord: "Alice"::p, tenant: "Bob"::p, terms: "test terms"}),
1071 "last".to_owned() => daml_value!({landlord: "John"::p, tenant: "Paul"::p, terms: "more test terms"})
1072 }));
1073 let actual = decode_apply(&dar, &json_value, &ty)?;
1074 assert_eq!(actual, expected);
1075 Ok(())
1076 }
1077
1078 #[test]
1080 fn test_genmap_int_empty() -> DamlJsonCodecResult<()> {
1081 let json_value = json!([]);
1082 let ty = DamlType::GenMap(vec![DamlType::Int64]);
1083 let expected = DamlValue::GenMap(vec![].into_iter().collect());
1084 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1085 assert_eq!(actual, expected);
1086 Ok(())
1087 }
1088
1089 #[test]
1091 fn test_genmap_string_to_int() -> DamlJsonCodecResult<()> {
1092 let json_value = json!([["foo", 42], ["bar", 43]]);
1093 let ty = DamlType::GenMap(vec![DamlType::Text, DamlType::Int64]);
1094 let expected = DamlValue::GenMap(
1095 vec![(daml_value!["foo"], daml_value![42]), (daml_value!["bar"], daml_value![43])].into_iter().collect(),
1096 );
1097 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1098 assert_eq!(actual, expected);
1099 Ok(())
1100 }
1101
1102 #[test]
1104 fn test_genmap_int_to_string() -> DamlJsonCodecResult<()> {
1105 let json_value = json!([[42, "foo"], [43, "bar"]]);
1106 let ty = DamlType::GenMap(vec![DamlType::Int64, DamlType::Text]);
1107 let expected = DamlValue::GenMap(
1108 vec![(daml_value![42], daml_value!["foo"]), (daml_value![43], daml_value!["bar"])].into_iter().collect(),
1109 );
1110 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty)?;
1111 assert_eq!(actual, expected);
1112 Ok(())
1113 }
1114
1115 #[test]
1118 fn test_genmap_person_to_string() -> DamlJsonCodecResult<()> {
1119 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1120 let json_value = json!([[{"name": "Alice", "age": 30}, "foo"], [{"name": "Bob", "age": 18}, "bar"]]);
1121 let key_type = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Person");
1122 let value_type = DamlType::Text;
1123 let ty = DamlType::GenMap(vec![key_type, value_type]);
1124 let expected = DamlValue::GenMap(
1125 vec![
1126 (daml_value![{name: "Alice", age: 30}], daml_value!["foo"]),
1127 (daml_value![{name: "Bob", age: 18}], daml_value!["bar"]),
1128 ]
1129 .into_iter()
1130 .collect(),
1131 );
1132 let actual = decode_apply(&dar, &json_value, &ty)?;
1133 assert_eq!(actual, expected);
1134 Ok(())
1135 }
1136
1137 #[test]
1138 fn test_genmap_duplicate_key_should_fail() {
1139 let json_value = json!([[42, "foo"], [42, "bar"]]);
1140 let ty = DamlType::GenMap(vec![DamlType::Int64, DamlType::Text]);
1141 let actual = JsonValueDecoder::new(&DamlArchive::default()).decode(&json_value, &ty);
1142 assert!(actual.is_err());
1143 }
1144
1145 #[test]
1147 fn test_variant_bar() -> DamlJsonCodecResult<()> {
1148 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1149 let json_value = json!({"tag": "Bar", "value": 42});
1150 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Foo");
1151 let expected = daml_value![{=>Bar 42}];
1152 let actual = decode_apply(&dar, &json_value, &ty)?;
1153 assert_eq!(actual, expected);
1154 Ok(())
1155 }
1156
1157 #[test]
1159 fn test_variant_baz() -> DamlJsonCodecResult<()> {
1160 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1161 let json_value = json!({"tag": "Baz", "value": {}});
1162 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Foo");
1163 let expected = daml_value![{=>Baz}];
1164 let actual = decode_apply(&dar, &json_value, &ty)?;
1165 assert_eq!(actual, expected);
1166 Ok(())
1167 }
1168
1169 #[test]
1171 fn test_variant_quux_none() -> DamlJsonCodecResult<()> {
1172 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1173 let json_value = json!({"tag": "Quux", "value": null});
1174 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Foo");
1175 let expected = daml_value![{=>Quux {?!}}];
1176 let actual = decode_apply(&dar, &json_value, &ty)?;
1177 assert_eq!(actual, expected);
1178 Ok(())
1179 }
1180
1181 #[test]
1183 fn test_variant_quux_some() -> DamlJsonCodecResult<()> {
1184 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1185 let json_value = json!({"tag": "Quux", "value": 42});
1186 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Foo");
1187 let expected = daml_value![{=>Quux {?=42}}];
1188 let actual = decode_apply(&dar, &json_value, &ty)?;
1189 assert_eq!(actual, expected);
1190 Ok(())
1191 }
1192
1193 #[test]
1195 fn test_enum_enabled() -> DamlJsonCodecResult<()> {
1196 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1197 let json_value = json!("Enabled");
1198 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Status");
1199 let expected = DamlValue::Enum(DamlEnum::new("Enabled", None));
1200 let actual = decode_apply(&dar, &json_value, &ty)?;
1201 assert_eq!(actual, expected);
1202 Ok(())
1203 }
1204
1205 #[test]
1207 fn test_enum_disabled() -> DamlJsonCodecResult<()> {
1208 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1209 let json_value = json!("Disabled");
1210 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Status");
1211 let expected = DamlValue::Enum(DamlEnum::new("Disabled", None));
1212 let actual = decode_apply(&dar, &json_value, &ty)?;
1213 assert_eq!(actual, expected);
1214 Ok(())
1215 }
1216
1217 #[test]
1219 fn test_enum_unknown_error() -> DamlJsonCodecResult<()> {
1220 let dar = DarFile::from_file(TESTING_TYPES_DAR_PATH)?;
1221 let json_value = json!("Unknown");
1222 let ty = DamlType::make_tycon(&dar.main.hash, &["Fuji", "JsonTest"], "Status");
1223 let actual = decode_apply(&dar, &json_value, &ty);
1224 assert!(actual.is_err());
1225 Ok(())
1226 }
1227
1228 fn decode_apply(dar: &DarFile, json_value: &Value, ty: &DamlType<'_>) -> DamlJsonCodecResult<DamlValue> {
1229 dar.apply(|arc| {
1230 let decoded_value = JsonValueDecoder::new(arc).decode(json_value, ty)?;
1231 Ok::<DamlValue, DamlJsonCodecError>(decoded_value)
1232 })?
1233 }
1234}