1use crate::error::DamlJsonCodecResult;
2use crate::util::Required;
3use bigdecimal::ToPrimitive;
4use chrono::SecondsFormat;
5use daml_grpc::data::value::{DamlRecord, DamlValue};
6use serde_json::{json, Value};
7use std::collections::HashMap;
8
9#[derive(Debug, Default)]
11pub struct JsonValueEncoder {
12 encode_decimal_as_string: bool,
13 encode_int64_as_string: bool,
14}
15
16impl JsonValueEncoder {
17 pub const fn new(encode_decimal_as_string: bool, encode_int64_as_string: bool) -> Self {
18 Self {
19 encode_decimal_as_string,
20 encode_int64_as_string,
21 }
22 }
23
24 pub fn encode_value(&self, value: &DamlValue) -> DamlJsonCodecResult<Value> {
26 self.do_encode_value(value, true)
27 }
28
29 pub fn encode_record(&self, record: &DamlRecord) -> DamlJsonCodecResult<Value> {
31 self.do_encode_record(record)
32 }
33
34 fn do_encode_value(&self, value: &DamlValue, top_level: bool) -> DamlJsonCodecResult<Value> {
49 match value {
50 DamlValue::Unit => Ok(json!({})),
51 DamlValue::Bool(b) => Ok(json!(b)),
52 DamlValue::Int64(i) =>
53 if self.encode_int64_as_string {
54 Ok(json!(format!("{}", i)))
55 } else {
56 Ok(json!(i))
57 },
58 DamlValue::Numeric(n) =>
59 if self.encode_decimal_as_string {
60 Ok(json!(format!("{}", n)))
61 } else {
62 Ok(json!(n.to_f64().req()?))
63 },
64 DamlValue::Timestamp(timestamp) => Ok(json!(timestamp.to_rfc3339_opts(SecondsFormat::Millis, true))),
65 DamlValue::Date(date) => Ok(json!(date.naive_utc().to_string())),
66 DamlValue::Text(text) => Ok(json!(text)),
67 DamlValue::Party(party) => Ok(json!(party.party)),
68 DamlValue::ContractId(id) => Ok(json!(id.contract_id)),
69 DamlValue::Optional(opt) => match opt {
70 None if top_level => Ok(json!(null)),
71 None => Ok(json!([])),
72 Some(inner) if top_level => Ok(json!(self.do_encode_value(inner, false)?)),
73 Some(inner) => Ok(json!([self.do_encode_value(inner, false)?])),
74 },
75 DamlValue::Record(record) => self.do_encode_record(record),
76 DamlValue::List(list) => {
77 let items =
78 list.iter().map(|i| self.do_encode_value(i, true)).collect::<DamlJsonCodecResult<Vec<_>>>()?;
79 Ok(json!(items))
80 },
81 DamlValue::Map(map) => {
82 let entries = map
83 .iter()
84 .map(|(k, v)| Ok((k.as_str(), self.do_encode_value(v, true)?)))
85 .collect::<DamlJsonCodecResult<HashMap<_, _>>>()?;
86 Ok(json!(entries))
87 },
88 DamlValue::Variant(variant) => {
89 let ctor = variant.constructor();
90 let value = self.do_encode_value(variant.value(), true)?;
91 Ok(json!({"tag": ctor, "value": value}))
92 },
93 DamlValue::Enum(data_enum) => Ok(json!(data_enum.constructor())),
94 DamlValue::GenMap(map) => {
95 let entries = map
96 .iter()
97 .map(|(k, v)| Ok((self.do_encode_value(k, true)?, self.do_encode_value(v, true)?)))
98 .collect::<DamlJsonCodecResult<Vec<(_, _)>>>()?;
99 Ok(json!(entries))
100 },
101 }
102 }
103
104 fn do_encode_record(&self, record: &DamlRecord) -> DamlJsonCodecResult<Value> {
106 let has_labels = record.fields().iter().all(|f| f.label().is_some());
107 if has_labels {
108 let fields = record
109 .fields()
110 .iter()
111 .filter(|f| !matches!(f.value(), DamlValue::Optional(None)))
112 .map(|f| Ok((f.label().as_ref().req()?, self.do_encode_value(f.value(), true)?)))
113 .collect::<DamlJsonCodecResult<HashMap<_, _>>>()?;
114 Ok(json!(fields))
115 } else {
116 let fields = record
117 .fields()
118 .iter()
119 .map(|f| self.do_encode_value(f.value(), true))
120 .collect::<DamlJsonCodecResult<Vec<_>>>()?;
121 Ok(json!(fields))
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::{DamlJsonCodecResult, DamlValue, JsonValueEncoder};
129 use crate::util::Required;
130 use crate::value_decode::JsonTryAsExt;
131 use daml::macros::daml_value;
132 use daml_grpc::data::value::{DamlEnum, DamlRecord, DamlRecordField};
133 use daml_grpc::data::DamlIdentifier;
134 use daml_grpc::primitive_types::DamlTextMap;
135 use maplit::hashmap;
136 use serde_json::{json, Value};
137
138 #[test]
139 fn test_unit() -> DamlJsonCodecResult<()> {
140 let grpc_value = daml_value!();
141 let expected = json!({});
142 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
143 assert_eq!(actual, expected);
144 Ok(())
145 }
146
147 #[test]
148 fn test_bool() -> DamlJsonCodecResult<()> {
149 let grpc_value = daml_value!(true);
150 let expected = json!(true);
151 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
152 assert_eq!(actual, expected);
153 Ok(())
154 }
155
156 #[test]
157 fn test_i64() -> DamlJsonCodecResult<()> {
158 let grpc_value = daml_value!(42);
159 let expected = json!(42);
160 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
161 assert_eq!(actual, expected);
162 Ok(())
163 }
164
165 #[test]
166 fn test_i64_neg() -> DamlJsonCodecResult<()> {
167 let grpc_value = daml_value!(-42);
168 let expected = json!(-42);
169 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
170 assert_eq!(actual, expected);
171 Ok(())
172 }
173
174 #[test]
175 fn test_i64_as_string() -> DamlJsonCodecResult<()> {
176 let grpc_value = daml_value!(42);
177 let expected = json!("42");
178 let actual = JsonValueEncoder::new(false, true).encode_value(&grpc_value)?;
179 assert_eq!(actual, expected);
180 Ok(())
181 }
182
183 #[test]
184 fn test_i64_neg_as_string() -> DamlJsonCodecResult<()> {
185 let grpc_value = daml_value!(-42);
186 let expected = json!("-42");
187 let actual = JsonValueEncoder::new(false, true).encode_value(&grpc_value)?;
188 assert_eq!(actual, expected);
189 Ok(())
190 }
191
192 #[test]
193 fn test_numeric() -> DamlJsonCodecResult<()> {
194 let grpc_value = daml_value!(1.0);
195 let expected = json!(1.0);
196 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
197 assert_eq!(actual, expected);
198 Ok(())
199 }
200
201 #[test]
202 fn test_numeric_neg() -> DamlJsonCodecResult<()> {
203 let grpc_value = daml_value!(-1.0);
204 let expected = json!(-1.0);
205 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
206 assert_eq!(actual, expected);
207 Ok(())
208 }
209
210 #[test]
211 fn test_numeric_as_string() -> DamlJsonCodecResult<()> {
212 let grpc_value = daml_value!(1.000_000_000_000_000);
213 let expected = json!("1.000000000000000");
214 let actual = JsonValueEncoder::new(true, false).encode_value(&grpc_value)?;
215 assert_eq!(actual, expected);
216 Ok(())
217 }
218
219 #[test]
220 fn test_numeric_neg_as_string() -> DamlJsonCodecResult<()> {
221 let grpc_value = daml_value!(-1.000_000_000_000_000);
222 let expected = json!("-1.000000000000000");
223 let actual = JsonValueEncoder::new(true, false).encode_value(&grpc_value)?;
224 assert_eq!(actual, expected);
225 Ok(())
226 }
227
228 #[test]
229 fn test_text() -> DamlJsonCodecResult<()> {
230 let grpc_value = daml_value!("test");
231 let expected = json!("test");
232 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
233 assert_eq!(actual, expected);
234 Ok(())
235 }
236
237 #[test]
238 fn test_text_empty() -> DamlJsonCodecResult<()> {
239 let grpc_value = daml_value!("");
240 let expected = json!("");
241 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
242 assert_eq!(actual, expected);
243 Ok(())
244 }
245
246 #[test]
247 fn test_date() -> DamlJsonCodecResult<()> {
248 let grpc_value = daml_value!("2019-06-18"::d);
249 let expected = json!("2019-06-18");
250 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
251 assert_eq!(actual, expected);
252 Ok(())
253 }
254
255 #[test]
256 fn test_date_min() -> DamlJsonCodecResult<()> {
257 let grpc_value = daml_value!("9999-12-31"::d);
258 let expected = json!("9999-12-31");
259 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
260 assert_eq!(actual, expected);
261 Ok(())
262 }
263
264 #[test]
265 fn test_date_max() -> DamlJsonCodecResult<()> {
266 let grpc_value = daml_value!("0001-01-01"::d);
267 let expected = json!("0001-01-01");
268 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
269 assert_eq!(actual, expected);
270 Ok(())
271 }
272
273 #[test]
274 fn test_timestamp_full() -> DamlJsonCodecResult<()> {
275 let grpc_value = daml_value!("1990-11-09T04:30:23.1234569Z"::t);
276 let expected = json!("1990-11-09T04:30:23.123Z");
277 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
278 assert_eq!(actual, expected);
279 Ok(())
280 }
281
282 #[test]
283 fn test_timestamp_no_sub_sec() -> DamlJsonCodecResult<()> {
284 let grpc_value = daml_value!("1990-11-09T04:30:23Z"::t);
285 let expected = json!("1990-11-09T04:30:23.000Z");
286 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
287 assert_eq!(actual, expected);
288 Ok(())
289 }
290
291 #[test]
292 fn test_timestamp_no_micros() -> DamlJsonCodecResult<()> {
293 let grpc_value = daml_value!("1990-11-09T04:30:23.123Z"::t);
294 let expected = json!("1990-11-09T04:30:23.123Z");
295 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
296 assert_eq!(actual, expected);
297 Ok(())
298 }
299
300 #[test]
301 fn test_timestamp_min() -> DamlJsonCodecResult<()> {
302 let grpc_value = daml_value!("0001-01-01T00:00:00Z"::t);
303 let expected = json!("0001-01-01T00:00:00.000Z");
304 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
305 assert_eq!(actual, expected);
306 Ok(())
307 }
308
309 #[test]
310 fn test_timestamp_max() -> DamlJsonCodecResult<()> {
311 let grpc_value = daml_value!("9999-12-31T23:59:59.999999Z"::t);
312 let expected = json!("9999-12-31T23:59:59.999Z");
313 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
314 assert_eq!(actual, expected);
315 Ok(())
316 }
317
318 #[test]
319 fn test_party() -> DamlJsonCodecResult<()> {
320 let grpc_value = daml_value!("Alice"::p);
321 let expected = json!("Alice");
322 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
323 assert_eq!(actual, expected);
324 Ok(())
325 }
326
327 #[test]
328 fn test_contract_id() -> DamlJsonCodecResult<()> {
329 let grpc_value = daml_value!("#0:0"::c);
330 let expected = json!("#0:0");
331 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
332 assert_eq!(actual, expected);
333 Ok(())
334 }
335
336 #[test]
337 fn test_opt_none() -> DamlJsonCodecResult<()> {
338 let grpc_value = daml_value!({?!});
339 let expected = json!(null);
340 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
341 assert_eq!(actual, expected);
342 Ok(())
343 }
344
345 #[test]
346 fn test_opt_int_some() -> DamlJsonCodecResult<()> {
347 let grpc_value = daml_value!({?=42});
348 let expected = json!(42);
349 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
350 assert_eq!(actual, expected);
351 Ok(())
352 }
353
354 #[test]
355 fn test_opt_opt_int_some_none() -> DamlJsonCodecResult<()> {
356 let grpc_value = daml_value!({?={?!}});
357 let expected = json!([]);
358 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
359 assert_eq!(actual, expected);
360 Ok(())
361 }
362
363 #[test]
364 fn test_opt_opt_int_some_some() -> DamlJsonCodecResult<()> {
365 let grpc_value = daml_value!({?={?=42}});
366 let expected = json!([42]);
367 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
368 assert_eq!(actual, expected);
369 Ok(())
370 }
371
372 #[test]
373 fn test_opt_opt_opt_int_some_some_none() -> DamlJsonCodecResult<()> {
374 let grpc_value = daml_value!({?={?={?!}}});
375 let expected = json!([[]]);
376 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
377 assert_eq!(actual, expected);
378 Ok(())
379 }
380
381 #[test]
382 fn test_opt_opt_opt_int_some_some_some() -> DamlJsonCodecResult<()> {
383 let grpc_value = daml_value!({?={?={?=42}}});
384 let expected = json!([[42]]);
385 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
386 assert_eq!(actual, expected);
387 Ok(())
388 }
389
390 #[test]
391 fn test_opt_opt_opt_opt_int_some_some_some_none() -> DamlJsonCodecResult<()> {
392 let grpc_value = daml_value!({?={?={?={?!}}}});
393 let expected = json!([[[]]]);
394 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
395 assert_eq!(actual, expected);
396 Ok(())
397 }
398
399 #[test]
400 fn test_opt_opt_opt_opt_text_some_some_some_some() -> DamlJsonCodecResult<()> {
401 let grpc_value = daml_value!({?={?={?={?="Test"}}}});
402 let expected = json!([[["Test"]]]);
403 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
404 assert_eq!(actual, expected);
405 Ok(())
406 }
407
408 #[test]
409 fn test_opt_unit_some() -> DamlJsonCodecResult<()> {
410 let grpc_value = daml_value!({?=()});
411 let expected = json!({});
412 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
413 assert_eq!(actual, expected);
414 Ok(())
415 }
416
417 #[test]
418 fn test_empty_record() -> DamlJsonCodecResult<()> {
419 let grpc_value = daml_value!({});
420 let expected = json!({});
421 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
422 assert_eq!(actual, expected);
423 Ok(())
424 }
425
426 #[test]
427 fn test_record() -> DamlJsonCodecResult<()> {
428 let grpc_value = daml_value!({landlord: "Alice"::p, tenant: "Bob"::p, terms: "test terms"});
429 let expected = json!({
430 "landlord": "Alice",
431 "tenant": "Bob",
432 "terms": "test terms",
433 });
434 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
435 assert_eq!(actual, expected);
436 Ok(())
437 }
438
439 #[test]
440 fn test_record_as_array() -> DamlJsonCodecResult<()> {
441 let grpc_value = DamlValue::new_record(DamlRecord::new(
442 vec![
443 DamlRecordField::new(None::<String>, DamlValue::new_party("Alice")),
444 DamlRecordField::new(None::<String>, DamlValue::new_party("Bob")),
445 DamlRecordField::new(None::<String>, DamlValue::new_text("test terms")),
446 ],
447 None::<DamlIdentifier>,
448 ));
449 let expected = json!(["Alice", "Bob", "test terms"]);
450 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
451 assert_eq!(actual, expected);
452 Ok(())
453 }
454
455 #[test]
459 fn test_record_depth1_omitted_or_none() -> DamlJsonCodecResult<()> {
460 let grpc_value = daml_value!({foo: {?!}});
461 let expected = json!({});
462 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
463 assert_eq!(actual, expected);
464 Ok(())
465 }
466
467 #[test]
469 fn test_record_depth1_some() -> DamlJsonCodecResult<()> {
470 let grpc_value = daml_value!({foo: {?=42}});
471 let expected = json!({ "foo": 42 });
472 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
473 assert_eq!(actual, expected);
474 Ok(())
475 }
476
477 #[test]
481 fn test_record_depth2_omitted_or_none() -> DamlJsonCodecResult<()> {
482 let grpc_value = daml_value!({foo: {?!}});
483 let expected = json!({});
484 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
485 assert_eq!(actual, expected);
486 Ok(())
487 }
488
489 #[test]
491 fn test_record_depth2_some_none() -> DamlJsonCodecResult<()> {
492 let grpc_value = daml_value!({foo: {?={?!}}});
493 let expected = json!({ "foo": [] });
494 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
495 assert_eq!(actual, expected);
496 Ok(())
497 }
498
499 #[test]
501 fn test_record_depth2_some_some() -> DamlJsonCodecResult<()> {
502 let grpc_value = daml_value!({foo: {?={?=42}}});
503 let expected = json!({ "foo": [42] });
504 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
505 assert_eq!(actual, expected);
506 Ok(())
507 }
508
509 #[test]
510 fn test_list_empty() -> DamlJsonCodecResult<()> {
511 let grpc_value = daml_value!([]);
512 let expected = json!([]);
513 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
514 assert_eq!(actual, expected);
515 Ok(())
516 }
517
518 #[test]
519 fn test_list_bool() -> DamlJsonCodecResult<()> {
520 let grpc_value = daml_value!([true, true, false, false]);
521 let expected = json!([true, true, false, false]);
522 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
523 assert_eq!(actual, expected);
524 Ok(())
525 }
526
527 #[test]
528 fn test_list_text() -> DamlJsonCodecResult<()> {
529 let grpc_value = daml_value!(["a", "b", "c"]);
530 let expected = json!(["a", "b", "c"]);
531 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
532 assert_eq!(actual, expected);
533 Ok(())
534 }
535
536 #[test]
537 fn test_list_opt_text() -> DamlJsonCodecResult<()> {
538 let grpc_value = daml_value!([{?="a"}, {?!}, {?="c"}]);
539 let expected = json!(["a", null, "c"]);
540 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
541 assert_eq!(actual, expected);
542 Ok(())
543 }
544
545 #[test]
546 fn test_list_record() -> DamlJsonCodecResult<()> {
547 let grpc_value = daml_value!([{
548 landlord: "Alice"::p,
549 tenant: "Bob"::p,
550 terms: "test terms"
551 },
552 {
553 landlord: "John"::p,
554 tenant: "Paul"::p,
555 terms: "more test terms"
556 }]);
557 let expected = json!([{
558 "landlord": "Alice",
559 "tenant": "Bob",
560 "terms": "test terms",
561 },
562 {
563 "landlord": "John",
564 "tenant": "Paul",
565 "terms": "more test terms",
566 }]);
567 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
568 assert_eq!(actual, expected);
569 Ok(())
570 }
571
572 #[test]
573 fn test_textmap_empty() -> DamlJsonCodecResult<()> {
574 let grpc_value = DamlValue::Map(vec![].into_iter().collect());
575 let expected = json!({});
576 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
577 assert_eq!(actual, expected);
578 Ok(())
579 }
580
581 #[test]
582 fn test_textmap_int() -> DamlJsonCodecResult<()> {
583 let grpc_value = DamlValue::Map(
584 vec![("foo".to_owned(), daml_value![42]), ("bar".to_owned(), daml_value![43])].into_iter().collect(),
585 );
586 let expected = json!({"foo": 42, "bar": 43});
587 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
588 assert_eq!(actual, expected);
589 Ok(())
590 }
591
592 #[test]
593 fn test_textmap_list_int() -> DamlJsonCodecResult<()> {
594 let grpc_value = DamlValue::Map(DamlTextMap::from(hashmap! {
595 "foo".to_owned() => daml_value![[1, 2, 3]],
596 "bar".to_owned() => daml_value![[4, 5, 6]]
597 }));
598 let expected = json!({"foo": [1, 2, 3], "bar": [4, 5, 6]});
599 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
600 assert_eq!(actual, expected);
601 Ok(())
602 }
603
604 #[test]
605 fn test_textmap_record() -> DamlJsonCodecResult<()> {
606 let grpc_value = DamlValue::Map(DamlTextMap::from(hashmap! {
607 "first".to_owned() => daml_value!({landlord: "Alice"::p, tenant: "Bob"::p, terms: "test terms"}),
608 "last".to_owned() => daml_value!({landlord: "John"::p, tenant: "Paul"::p, terms: "more test terms"})
609 }));
610 let expected = json!({
611 "first": {
612 "landlord": "Alice",
613 "tenant": "Bob",
614 "terms": "test terms",
615 },
616 "last": {
617 "landlord": "John",
618 "tenant": "Paul",
619 "terms": "more test terms",
620 }});
621 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
622 assert_eq!(actual, expected);
623 Ok(())
624 }
625
626 #[test]
627 fn test_genmap_empty() -> DamlJsonCodecResult<()> {
628 let grpc_value = DamlValue::GenMap(vec![].into_iter().collect());
629 let expected = json!([]);
630 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
631 assert_eq!(actual, expected);
632 Ok(())
633 }
634
635 #[test]
636 fn test_genmap_string_to_int() -> DamlJsonCodecResult<()> {
637 let grpc_value = DamlValue::GenMap(
638 vec![(daml_value!["foo"], daml_value![42]), (daml_value!["bar"], daml_value![43])].into_iter().collect(),
639 );
640 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
641 let key_foo_value = find_genmap_value(&actual, &json!["foo"])?;
642 let key_bar_value = find_genmap_value(&actual, &json!["bar"])?;
643 assert_eq!(key_foo_value, &json![42]);
644 assert_eq!(key_bar_value, &json![43]);
645 Ok(())
646 }
647
648 #[test]
649 fn test_genmap_int_to_string() -> DamlJsonCodecResult<()> {
650 let grpc_value = DamlValue::GenMap(
651 vec![(daml_value![42], daml_value!["foo"]), (daml_value![43], daml_value!["bar"])].into_iter().collect(),
652 );
653 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
654 let key_42_value = find_genmap_value(&actual, &json![42])?;
655 let key_43_value = find_genmap_value(&actual, &json![43])?;
656 assert_eq!(key_42_value, &json!["foo"]);
657 assert_eq!(key_43_value, &json!["bar"]);
658 Ok(())
659 }
660
661 #[test]
662 fn test_genmap_person_to_string() -> DamlJsonCodecResult<()> {
663 let grpc_value = DamlValue::GenMap(
664 vec![
665 (daml_value![{name: "John", age: 29}], daml_value!["foo"]),
666 (daml_value![{name: "Alice", age: 22}], daml_value!["bar"]),
667 ]
668 .into_iter()
669 .collect(),
670 );
671 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
672 let key_john_value = find_genmap_value(&actual, &json![{"name": "John", "age": 29}])?;
673 let key_alice_value = find_genmap_value(&actual, &json![{"name": "Alice", "age": 22}])?;
674 assert_eq!(key_john_value, &json!["foo"]);
675 assert_eq!(key_alice_value, &json!["bar"]);
676 Ok(())
677 }
678
679 #[test]
680 fn test_variant_bar() -> DamlJsonCodecResult<()> {
681 let grpc_value = daml_value![{=>Bar 42}];
682 let expected = json!({"tag": "Bar", "value": 42});
683 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
684 assert_eq!(actual, expected);
685 Ok(())
686 }
687
688 #[test]
689 fn test_variant_baz() -> DamlJsonCodecResult<()> {
690 let grpc_value = daml_value![{=>Baz}];
691 let expected = json!({"tag": "Baz", "value": {}});
692 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
693 assert_eq!(actual, expected);
694 Ok(())
695 }
696
697 #[test]
698 fn test_variant_quuz_none() -> DamlJsonCodecResult<()> {
699 let grpc_value = daml_value![{=>Quux {?!}}];
700 let expected = json!({"tag": "Quux", "value": null});
701 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
702 assert_eq!(actual, expected);
703 Ok(())
704 }
705
706 #[test]
707 fn test_variant_quuz_some() -> DamlJsonCodecResult<()> {
708 let grpc_value = daml_value![{=>Quux {?=42}}];
709 let expected = json!({"tag": "Quux", "value": 42});
710 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
711 assert_eq!(actual, expected);
712 Ok(())
713 }
714
715 #[test]
716 fn test_enum_enabled() -> DamlJsonCodecResult<()> {
717 let grpc_value = DamlValue::Enum(DamlEnum::new("Enabled", None));
718 let expected = json!("Enabled");
719 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
720 assert_eq!(actual, expected);
721 Ok(())
722 }
723
724 #[test]
725 fn test_enum_disabled() -> DamlJsonCodecResult<()> {
726 let grpc_value = DamlValue::Enum(DamlEnum::new("Disabled", None));
727 let expected = json!("Disabled");
728 let actual = JsonValueEncoder::default().encode_value(&grpc_value)?;
729 assert_eq!(actual, expected);
730 Ok(())
731 }
732
733 fn find_genmap_value<'a>(genmap: &'a Value, key: &Value) -> DamlJsonCodecResult<&'a Value> {
734 Ok(genmap
735 .try_array()?
736 .iter()
737 .find_map(|item| (item.try_array().ok()?.first()? == key).then(|| item))
738 .req()?
739 .try_array()?
740 .last()
741 .req()?)
742 }
743}