1use jacquard_derive::lexicon;
2use serde::{Deserialize, Serialize};
3
4#[lexicon]
5#[derive(Serialize, Deserialize, Debug, PartialEq)]
6#[serde(rename_all = "camelCase")]
7struct TestRecord<'s> {
8 text: &'s str,
9 count: i64,
10}
11
12#[test]
13fn test_lexicon_adds_extra_data_field() {
14 let json = r#"{"text":"hello","count":42,"unknown":"field","another":123}"#;
15
16 let record: TestRecord = serde_json::from_str(json).unwrap();
17
18 assert_eq!(record.text, "hello");
19 assert_eq!(record.count, 42);
20 assert_eq!(record.extra_data.len(), 2);
21 assert!(record.extra_data.contains_key("unknown"));
22 assert!(record.extra_data.contains_key("another"));
23}
24
25#[test]
26fn test_lexicon_roundtrip() {
27 use jacquard_common::CowStr;
28 use jacquard_common::types::value::Data;
29 use std::collections::BTreeMap;
30
31 let mut extra = BTreeMap::new();
32 extra.insert(
33 "custom".into(),
34 Data::String(jacquard_common::types::string::AtprotoStr::String(
35 CowStr::Borrowed("value"),
36 )),
37 );
38 extra.insert(
39 "number".into(),
40 Data::Integer(42),
41 );
42 extra.insert(
43 "nested".into(),
44 Data::Object(jacquard_common::types::value::Object({
45 let mut nested_map = BTreeMap::new();
46 nested_map.insert(
47 "inner".into(),
48 Data::Boolean(true),
49 );
50 nested_map
51 })),
52 );
53
54 let record = TestRecord {
55 text: "test",
56 count: 100,
57 extra_data: extra,
58 };
59
60 let json = serde_json::to_string(&record).unwrap();
61 let parsed: TestRecord = serde_json::from_str(&json).unwrap();
62
63 assert_eq!(record, parsed);
64 assert_eq!(parsed.extra_data.len(), 3);
65
66 // Verify the extra fields were preserved
67 assert!(parsed.extra_data.contains_key("custom"));
68 assert!(parsed.extra_data.contains_key("number"));
69 assert!(parsed.extra_data.contains_key("nested"));
70
71 // Verify the values
72 if let Some(Data::String(s)) = parsed.extra_data.get("custom") {
73 assert_eq!(s.as_str(), "value");
74 } else {
75 panic!("expected custom field to be a string");
76 }
77
78 if let Some(Data::Integer(n)) = parsed.extra_data.get("number") {
79 assert_eq!(*n, 42);
80 } else {
81 panic!("expected number field to be an integer");
82 }
83
84 if let Some(Data::Object(obj)) = parsed.extra_data.get("nested") {
85 assert!(obj.0.contains_key("inner"));
86 } else {
87 panic!("expected nested field to be an object");
88 }
89}