1use crate::decoder::{OffsetSizeBytes, VariantBasicType, VariantPrimitiveType};
18use crate::{
19 ShortString, Variant, VariantDecimal4, VariantDecimal8, VariantDecimal16, VariantList,
20 VariantMetadata, VariantObject,
21};
22use arrow_schema::ArrowError;
23use chrono::Timelike;
24use uuid::Uuid;
25
26mod list;
27mod metadata;
28mod object;
29
30pub use list::*;
31pub use metadata::*;
32pub use object::*;
33
34pub(crate) const BASIC_TYPE_BITS: u8 = 2;
35pub(crate) const UNIX_EPOCH_DATE: chrono::NaiveDate =
36 chrono::NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
37
38fn primitive_header(primitive_type: VariantPrimitiveType) -> u8 {
39 (primitive_type as u8) << 2 | VariantBasicType::Primitive as u8
40}
41
42fn short_string_header(len: usize) -> u8 {
43 (len as u8) << 2 | VariantBasicType::ShortString as u8
44}
45
46pub(crate) fn int_size(v: usize) -> OffsetSizeBytes {
47 match v {
48 0..=0xFF => OffsetSizeBytes::One,
49 0x100..=0xFFFF => OffsetSizeBytes::Two,
50 0x10000..=0xFFFFFF => OffsetSizeBytes::Three,
51 _ => OffsetSizeBytes::Four,
52 }
53}
54
55const ONE_TOP_LEVEL_VALUE_MSG: &str =
56 "VariantBuilder already contains a top-level variant value; only one is allowed";
57const EMPTY_BUILDER_MSG: &str =
58 "VariantBuilder is empty; append a top-level value before calling finish()";
59
60#[cold]
63#[inline(never)]
64fn top_level_value_panic() -> ! {
65 panic!("{ONE_TOP_LEVEL_VALUE_MSG}");
66}
67
68#[cold]
69#[inline(never)]
70fn top_level_value_error() -> ArrowError {
71 ArrowError::InvalidArgumentError(ONE_TOP_LEVEL_VALUE_MSG.into())
72}
73
74#[cold]
75#[inline(never)]
76fn empty_builder_error() -> ArrowError {
77 ArrowError::InvalidArgumentError(EMPTY_BUILDER_MSG.into())
78}
79
80#[derive(Debug, Default)]
88pub struct ValueBuilder(Vec<u8>);
89
90impl ValueBuilder {
91 pub fn new() -> Self {
93 Default::default()
94 }
95}
96
97macro_rules! variant_append_value {
100 ($builder:expr, $value:expr, $object_pat:pat => $object_arm:expr, $list_pat:pat => $list_arm:expr) => {
101 match $value {
102 Variant::Null => $builder.append_null(),
103 Variant::BooleanTrue => $builder.append_bool(true),
104 Variant::BooleanFalse => $builder.append_bool(false),
105 Variant::Int8(v) => $builder.append_int8(v),
106 Variant::Int16(v) => $builder.append_int16(v),
107 Variant::Int32(v) => $builder.append_int32(v),
108 Variant::Int64(v) => $builder.append_int64(v),
109 Variant::Date(v) => $builder.append_date(v),
110 Variant::Time(v) => $builder.append_time_micros(v),
111 Variant::TimestampMicros(v) => $builder.append_timestamp_micros(v),
112 Variant::TimestampNtzMicros(v) => $builder.append_timestamp_ntz_micros(v),
113 Variant::TimestampNanos(v) => $builder.append_timestamp_nanos(v),
114 Variant::TimestampNtzNanos(v) => $builder.append_timestamp_ntz_nanos(v),
115 Variant::Decimal4(decimal4) => $builder.append_decimal4(decimal4),
116 Variant::Decimal8(decimal8) => $builder.append_decimal8(decimal8),
117 Variant::Decimal16(decimal16) => $builder.append_decimal16(decimal16),
118 Variant::Float(v) => $builder.append_float(v),
119 Variant::Double(v) => $builder.append_double(v),
120 Variant::Binary(v) => $builder.append_binary(v),
121 Variant::String(s) => $builder.append_string(s),
122 Variant::ShortString(s) => $builder.append_short_string(s),
123 Variant::Uuid(v) => $builder.append_uuid(v),
124 $object_pat => $object_arm,
125 $list_pat => $list_arm,
126 }
127 };
128}
129
130impl ValueBuilder {
131 fn append_u8(&mut self, term: u8) {
132 self.0.push(term);
133 }
134
135 fn append_slice(&mut self, other: &[u8]) {
136 self.0.extend_from_slice(other);
137 }
138
139 fn append_primitive_header(&mut self, primitive_type: VariantPrimitiveType) {
140 self.0.push(primitive_header(primitive_type));
141 }
142
143 pub fn into_inner(self) -> Vec<u8> {
145 self.0
146 }
147
148 pub(crate) fn inner_mut(&mut self) -> &mut Vec<u8> {
149 &mut self.0
150 }
151
152 fn append_null(&mut self) {
155 self.append_primitive_header(VariantPrimitiveType::Null);
156 }
157
158 fn append_bool(&mut self, value: bool) {
159 let primitive_type = if value {
160 VariantPrimitiveType::BooleanTrue
161 } else {
162 VariantPrimitiveType::BooleanFalse
163 };
164 self.append_primitive_header(primitive_type);
165 }
166
167 fn append_int8(&mut self, value: i8) {
168 self.append_primitive_header(VariantPrimitiveType::Int8);
169 self.append_u8(value as u8);
170 }
171
172 fn append_int16(&mut self, value: i16) {
173 self.append_primitive_header(VariantPrimitiveType::Int16);
174 self.append_slice(&value.to_le_bytes());
175 }
176
177 fn append_int32(&mut self, value: i32) {
178 self.append_primitive_header(VariantPrimitiveType::Int32);
179 self.append_slice(&value.to_le_bytes());
180 }
181
182 fn append_int64(&mut self, value: i64) {
183 self.append_primitive_header(VariantPrimitiveType::Int64);
184 self.append_slice(&value.to_le_bytes());
185 }
186
187 fn append_float(&mut self, value: f32) {
188 self.append_primitive_header(VariantPrimitiveType::Float);
189 self.append_slice(&value.to_le_bytes());
190 }
191
192 fn append_double(&mut self, value: f64) {
193 self.append_primitive_header(VariantPrimitiveType::Double);
194 self.append_slice(&value.to_le_bytes());
195 }
196
197 fn append_date(&mut self, value: chrono::NaiveDate) {
198 self.append_primitive_header(VariantPrimitiveType::Date);
199 let days_since_epoch = value.signed_duration_since(UNIX_EPOCH_DATE).num_days() as i32;
200 self.append_slice(&days_since_epoch.to_le_bytes());
201 }
202
203 fn append_timestamp_micros(&mut self, value: chrono::DateTime<chrono::Utc>) {
204 self.append_primitive_header(VariantPrimitiveType::TimestampMicros);
205 let micros = value.timestamp_micros();
206 self.append_slice(µs.to_le_bytes());
207 }
208
209 fn append_timestamp_ntz_micros(&mut self, value: chrono::NaiveDateTime) {
210 self.append_primitive_header(VariantPrimitiveType::TimestampNtzMicros);
211 let micros = value.and_utc().timestamp_micros();
212 self.append_slice(µs.to_le_bytes());
213 }
214
215 fn append_time_micros(&mut self, value: chrono::NaiveTime) {
216 self.append_primitive_header(VariantPrimitiveType::Time);
217 let micros_from_midnight = value.num_seconds_from_midnight() as u64 * 1_000_000
218 + value.nanosecond() as u64 / 1_000;
219 self.append_slice(µs_from_midnight.to_le_bytes());
220 }
221
222 fn append_timestamp_nanos(&mut self, value: chrono::DateTime<chrono::Utc>) {
223 self.append_primitive_header(VariantPrimitiveType::TimestampNanos);
224 let nanos = value.timestamp_nanos_opt().unwrap();
225 self.append_slice(&nanos.to_le_bytes());
226 }
227
228 fn append_timestamp_ntz_nanos(&mut self, value: chrono::NaiveDateTime) {
229 self.append_primitive_header(VariantPrimitiveType::TimestampNtzNanos);
230 let nanos = value.and_utc().timestamp_nanos_opt().unwrap();
231 self.append_slice(&nanos.to_le_bytes());
232 }
233
234 fn append_uuid(&mut self, value: Uuid) {
235 self.append_primitive_header(VariantPrimitiveType::Uuid);
236 self.append_slice(&value.into_bytes());
237 }
238
239 fn append_decimal4(&mut self, decimal4: VariantDecimal4) {
240 self.append_primitive_header(VariantPrimitiveType::Decimal4);
241 self.append_u8(decimal4.scale());
242 self.append_slice(&decimal4.integer().to_le_bytes());
243 }
244
245 fn append_decimal8(&mut self, decimal8: VariantDecimal8) {
246 self.append_primitive_header(VariantPrimitiveType::Decimal8);
247 self.append_u8(decimal8.scale());
248 self.append_slice(&decimal8.integer().to_le_bytes());
249 }
250
251 fn append_decimal16(&mut self, decimal16: VariantDecimal16) {
252 self.append_primitive_header(VariantPrimitiveType::Decimal16);
253 self.append_u8(decimal16.scale());
254 self.append_slice(&decimal16.integer().to_le_bytes());
255 }
256
257 fn append_binary(&mut self, value: &[u8]) {
258 self.append_primitive_header(VariantPrimitiveType::Binary);
259 self.append_slice(&(value.len() as u32).to_le_bytes());
260 self.append_slice(value);
261 }
262
263 fn append_short_string(&mut self, value: ShortString) {
264 let inner = value.0;
265 self.append_u8(short_string_header(inner.len()));
266 self.append_slice(inner.as_bytes());
267 }
268
269 fn append_string(&mut self, value: &str) {
270 self.append_primitive_header(VariantPrimitiveType::String);
271 self.append_slice(&(value.len() as u32).to_le_bytes());
272 self.append_slice(value.as_bytes());
273 }
274
275 fn append_object<S: BuilderSpecificState>(state: ParentState<'_, S>, obj: VariantObject) {
276 let mut object_builder = ObjectBuilder::new(state, false);
277 object_builder.extend(obj.iter());
278 object_builder.finish();
279 }
280
281 fn try_append_object<S: BuilderSpecificState>(
282 state: ParentState<'_, S>,
283 obj: VariantObject,
284 ) -> Result<(), ArrowError> {
285 let mut object_builder = ObjectBuilder::new(state, false);
286
287 for res in obj.iter_try() {
288 let (field_name, value) = res?;
289 object_builder.try_insert(field_name, value)?;
290 }
291
292 object_builder.finish();
293 Ok(())
294 }
295
296 fn append_list<S: BuilderSpecificState>(state: ParentState<'_, S>, list: VariantList) {
297 let mut list_builder = ListBuilder::new(state, false);
298 list_builder.extend(list.iter());
299 list_builder.finish();
300 }
301
302 fn try_append_list<S: BuilderSpecificState>(
303 state: ParentState<'_, S>,
304 list: VariantList,
305 ) -> Result<(), ArrowError> {
306 let mut list_builder = ListBuilder::new(state, false);
307 for res in list.iter_try() {
308 let value = res?;
309 list_builder.try_append_value(value)?;
310 }
311
312 list_builder.finish();
313
314 Ok(())
315 }
316
317 pub fn offset(&self) -> usize {
319 self.0.len()
320 }
321
322 pub fn append_variant<S: BuilderSpecificState>(
329 mut state: ParentState<'_, S>,
330 variant: Variant<'_, '_>,
331 ) {
332 variant_append_value!(
333 state.value_builder(),
334 variant,
335 Variant::Object(obj) => return Self::append_object(state, obj),
336 Variant::List(list) => return Self::append_list(state, list)
337 );
338 state.finish();
339 }
340
341 pub fn try_append_variant<S: BuilderSpecificState>(
346 mut state: ParentState<'_, S>,
347 variant: Variant<'_, '_>,
348 ) -> Result<(), ArrowError> {
349 variant_append_value!(
350 state.value_builder(),
351 variant,
352 Variant::Object(obj) => return Self::try_append_object(state, obj),
353 Variant::List(list) => return Self::try_append_list(state, list)
354 );
355 state.finish();
356 Ok(())
357 }
358
359 pub fn append_variant_bytes<S: BuilderSpecificState>(
368 mut state: ParentState<'_, S>,
369 variant: Variant<'_, '_>,
370 ) {
371 let builder = state.value_builder();
372 variant_append_value!(
373 builder,
374 variant,
375 Variant::Object(obj) => builder.append_slice(obj.value),
376 Variant::List(list) => builder.append_slice(list.value)
377 );
378 state.finish();
379 }
380}
381
382pub trait BuilderSpecificState: std::fmt::Debug {
384 fn finish(
392 &mut self,
393 _metadata_builder: &mut dyn MetadataBuilder,
394 _value_builder: &mut ValueBuilder,
395 ) {
396 }
397
398 fn rollback(&mut self) {}
406}
407
408impl BuilderSpecificState for () {}
410
411#[derive(Debug)]
423pub struct ParentState<'a, S: BuilderSpecificState> {
424 pub(crate) value_builder: &'a mut ValueBuilder,
425 pub(crate) saved_value_builder_offset: usize,
426 pub(crate) metadata_builder: &'a mut dyn MetadataBuilder,
427 pub(crate) saved_metadata_builder_dict_size: usize,
428 pub(crate) builder_state: S,
429 pub(crate) finished: bool,
430}
431
432impl<'a, S: BuilderSpecificState> ParentState<'a, S> {
433 pub fn new(
437 value_builder: &'a mut ValueBuilder,
438 metadata_builder: &'a mut dyn MetadataBuilder,
439 builder_state: S,
440 ) -> Self {
441 Self {
442 saved_value_builder_offset: value_builder.offset(),
443 value_builder,
444 saved_metadata_builder_dict_size: metadata_builder.num_field_names(),
445 metadata_builder,
446 builder_state,
447 finished: false,
448 }
449 }
450
451 pub fn finish(&mut self) {
454 self.builder_state
455 .finish(self.metadata_builder, self.value_builder);
456 self.finished = true
457 }
458
459 fn rollback(&mut self) {
461 if self.finished {
462 return;
463 }
464
465 self.value_builder
466 .inner_mut()
467 .truncate(self.saved_value_builder_offset);
468 self.metadata_builder
469 .truncate_field_names(self.saved_metadata_builder_dict_size);
470 self.builder_state.rollback();
471 }
472
473 pub(crate) fn value_builder(&mut self) -> &mut ValueBuilder {
475 self.value_builder
476 }
477
478 pub(crate) fn metadata_builder(&mut self) -> &mut dyn MetadataBuilder {
480 self.metadata_builder
481 }
482}
483
484impl<'a> ParentState<'a, ()> {
485 pub fn variant(
489 value_builder: &'a mut ValueBuilder,
490 metadata_builder: &'a mut dyn MetadataBuilder,
491 ) -> Self {
492 Self::new(value_builder, metadata_builder, ())
493 }
494}
495
496impl<S: BuilderSpecificState> Drop for ParentState<'_, S> {
498 fn drop(&mut self) {
499 self.rollback()
500 }
501}
502
503#[derive(Default, Debug)]
746pub struct VariantBuilder {
747 value_builder: ValueBuilder,
748 metadata_builder: WritableMetadataBuilder,
749 validate_unique_fields: bool,
750}
751
752impl VariantBuilder {
753 pub fn new() -> Self {
755 Self {
756 value_builder: ValueBuilder::new(),
757 metadata_builder: WritableMetadataBuilder::default(),
758 validate_unique_fields: false,
759 }
760 }
761
762 pub fn with_metadata(mut self, metadata: VariantMetadata) -> Self {
764 self.metadata_builder.extend(metadata.iter());
765
766 self
767 }
768
769 pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self {
775 self.validate_unique_fields = validate_unique_fields;
776 self
777 }
778
779 pub fn with_field_names<'a>(mut self, field_names: impl IntoIterator<Item = &'a str>) -> Self {
786 self.metadata_builder.extend(field_names);
787
788 self
789 }
790
791 pub fn with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(mut self, value: T) -> Self {
798 self.append_value(value);
799 self
800 }
801
802 pub fn try_with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
806 mut self,
807 value: T,
808 ) -> Result<Self, ArrowError> {
809 self.try_append_value(value)?;
810 Ok(self)
811 }
812
813 pub fn reserve(&mut self, capacity: usize) {
817 self.metadata_builder.field_names.reserve(capacity);
818 }
819
820 pub fn add_field_name(&mut self, field_name: &str) {
824 self.metadata_builder.upsert_field_name(field_name);
825 }
826
827 #[inline]
833 fn has_top_level_value(&self) -> bool {
834 self.value_builder.offset() != 0
835 }
836
837 #[inline]
838 fn ensure_no_top_level_value(&self) {
839 if self.has_top_level_value() {
840 top_level_value_panic();
841 }
842 }
843
844 #[inline]
845 fn check_no_top_level_value(&self) -> Result<(), ArrowError> {
846 if self.has_top_level_value() {
847 return Err(top_level_value_error());
848 }
849 Ok(())
850 }
851
852 pub fn new_list(&mut self) -> ListBuilder<'_, ()> {
861 self.try_new_list().unwrap()
862 }
863
864 pub fn try_new_list(&mut self) -> Result<ListBuilder<'_, ()>, ArrowError> {
868 self.check_no_top_level_value()?;
869 let parent_state =
870 ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
871 Ok(ListBuilder::new(parent_state, self.validate_unique_fields))
872 }
873
874 pub fn new_object(&mut self) -> ObjectBuilder<'_, ()> {
883 self.try_new_object().unwrap()
884 }
885
886 pub fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, ()>, ArrowError> {
890 self.check_no_top_level_value()?;
891 let parent_state =
892 ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
893 Ok(ObjectBuilder::new(
894 parent_state,
895 self.validate_unique_fields,
896 ))
897 }
898
899 pub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T) {
915 self.ensure_no_top_level_value();
916 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
917 ValueBuilder::append_variant(state, value.into())
918 }
919
920 pub fn try_append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
924 &mut self,
925 value: T,
926 ) -> Result<(), ArrowError> {
927 self.check_no_top_level_value()?;
928 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
929 ValueBuilder::try_append_variant(state, value.into())
930 }
931
932 pub fn append_value_bytes<'m, 'd>(&mut self, value: impl Into<Variant<'m, 'd>>) {
946 self.try_append_value_bytes(value).unwrap()
947 }
948
949 pub fn try_append_value_bytes<'m, 'd>(
954 &mut self,
955 value: impl Into<Variant<'m, 'd>>,
956 ) -> Result<(), ArrowError> {
957 self.check_no_top_level_value()?;
958 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
959 ValueBuilder::append_variant_bytes(state, value.into());
960 Ok(())
961 }
962
963 pub fn finish(self) -> (Vec<u8>, Vec<u8>) {
970 self.try_finish().expect(EMPTY_BUILDER_MSG)
971 }
972
973 pub fn try_finish(mut self) -> Result<(Vec<u8>, Vec<u8>), ArrowError> {
977 if !self.has_top_level_value() {
978 return Err(empty_builder_error());
979 }
980 self.metadata_builder.finish();
981 Ok((
982 self.metadata_builder.into_inner(),
983 self.value_builder.into_inner(),
984 ))
985 }
986}
987
988pub trait VariantBuilderExt {
993 type State<'a>: BuilderSpecificState + 'a
995 where
996 Self: 'a;
997
998 fn append_null(&mut self);
1001
1002 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>);
1004
1005 fn new_list(&mut self) -> ListBuilder<'_, Self::State<'_>> {
1008 self.try_new_list().unwrap()
1009 }
1010
1011 fn new_object(&mut self) -> ObjectBuilder<'_, Self::State<'_>> {
1014 self.try_new_object().unwrap()
1015 }
1016
1017 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError>;
1020
1021 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError>;
1024}
1025
1026impl VariantBuilderExt for VariantBuilder {
1027 type State<'a>
1028 = ()
1029 where
1030 Self: 'a;
1031
1032 fn append_null(&mut self) {
1035 self.append_value(Variant::Null);
1036 }
1037 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>) {
1038 self.append_value(value);
1039 }
1040
1041 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError> {
1042 self.try_new_list()
1043 }
1044
1045 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError> {
1046 self.try_new_object()
1047 }
1048}
1049
1050#[cfg(test)]
1051mod tests {
1052 use crate::{VariantMetadata, builder::metadata::ReadOnlyMetadataBuilder};
1053
1054 use super::*;
1055 #[test]
1056 fn test_simple_usage() {
1057 test_variant_roundtrip((), Variant::Null);
1058 test_variant_roundtrip(true, Variant::BooleanTrue);
1059 test_variant_roundtrip(false, Variant::BooleanFalse);
1060 test_variant_roundtrip(42i8, Variant::Int8(42));
1061 test_variant_roundtrip(1234i16, Variant::Int16(1234));
1062 test_variant_roundtrip(123456i32, Variant::Int32(123456));
1063 test_variant_roundtrip(123456789i64, Variant::Int64(123456789));
1064 test_variant_roundtrip(1.5f32, Variant::Float(1.5));
1065 test_variant_roundtrip(2.5f64, Variant::Double(2.5));
1066 test_variant_roundtrip("hello", Variant::ShortString(ShortString("hello")));
1067
1068 let long_string = "This is a very long string that exceeds the short string limit of 63 bytes and should be encoded as a regular string type instead of a short string";
1070 test_variant_roundtrip(long_string, Variant::String(long_string));
1071
1072 let binary_data = b"binary data";
1074 test_variant_roundtrip(
1075 binary_data.as_slice(),
1076 Variant::Binary(binary_data.as_slice()),
1077 );
1078 }
1079
1080 fn test_variant_roundtrip<'m, 'd, T: Into<Variant<'m, 'd>>>(input: T, expected: Variant) {
1082 let mut builder = VariantBuilder::new();
1083 builder.append_value(input);
1084 let (metadata, value) = builder.finish();
1085 let variant = Variant::try_new(&metadata, &value).unwrap_or_else(|_| {
1086 panic!("Failed to create variant from metadata and value: {metadata:?}, {value:?}")
1087 });
1088 assert_eq!(variant, expected);
1089 }
1090
1091 #[test]
1092 fn test_try_finish_empty_builder_errors() {
1093 let builder = VariantBuilder::new();
1094 let err = builder.try_finish().unwrap_err();
1095 assert!(err.to_string().contains("empty"), "unexpected error: {err}");
1096 }
1097
1098 #[test]
1099 #[should_panic(expected = "empty")]
1100 fn test_finish_empty_builder_panics() {
1101 let builder = VariantBuilder::new();
1102 let _ = builder.finish();
1103 }
1104
1105 #[test]
1106 fn test_try_append_value_after_value_errors() {
1107 let mut builder = VariantBuilder::new();
1108 builder.append_value(1i32);
1109 let err = builder.try_append_value(2i32).unwrap_err();
1110 assert!(
1111 err.to_string().contains("only one is allowed"),
1112 "unexpected error: {err}"
1113 );
1114 }
1115
1116 #[test]
1117 fn test_try_append_value_bytes_after_value_errors() {
1118 let mut builder = VariantBuilder::new();
1119 builder.append_value(1i32);
1120 let err = builder.try_append_value_bytes(2i32).unwrap_err();
1121 assert!(
1122 err.to_string().contains("only one is allowed"),
1123 "unexpected error: {err}"
1124 );
1125 }
1126
1127 #[test]
1128 fn test_try_new_list_after_value_errors() {
1129 let mut builder = VariantBuilder::new();
1130 builder.append_value(1i32);
1131 let err = builder.try_new_list().expect_err("expected error");
1132 assert!(
1133 err.to_string().contains("only one is allowed"),
1134 "unexpected error: {err}"
1135 );
1136 }
1137
1138 #[test]
1139 fn test_try_new_object_after_value_errors() {
1140 let mut builder = VariantBuilder::new();
1141 builder.append_value(1i32);
1142 let err = builder.try_new_object().expect_err("expected error");
1143 assert!(
1144 err.to_string().contains("only one is allowed"),
1145 "unexpected error: {err}"
1146 );
1147 }
1148
1149 #[test]
1150 #[should_panic(expected = "only one is allowed")]
1151 fn test_append_value_after_value_panics() {
1152 let mut builder = VariantBuilder::new();
1153 builder.append_value(1i32);
1154 builder.append_value(2i32);
1155 }
1156
1157 #[test]
1158 #[should_panic(expected = "only one is allowed")]
1159 fn test_append_value_bytes_after_value_panics() {
1160 let mut builder = VariantBuilder::new();
1161 builder.append_value(1i32);
1162 builder.append_value_bytes(2i32);
1163 }
1164
1165 #[test]
1166 #[should_panic(expected = "only one is allowed")]
1167 fn test_new_list_after_value_panics() {
1168 let mut builder = VariantBuilder::new();
1169 builder.append_value(1i32);
1170 let _ = builder.new_list();
1171 }
1172
1173 #[test]
1174 #[should_panic(expected = "only one is allowed")]
1175 fn test_new_object_after_value_panics() {
1176 let mut builder = VariantBuilder::new();
1177 builder.append_value(1i32);
1178 let _ = builder.new_object();
1179 }
1180
1181 #[test]
1182 fn test_nested_object_with_lists() {
1183 let mut builder = VariantBuilder::new();
1193 {
1194 let mut outer_object_builder = builder.new_object();
1195 {
1196 let mut inner_object_builder = outer_object_builder.new_object("door 1");
1197
1198 inner_object_builder
1200 .new_list("items")
1201 .with_value("apple")
1202 .with_value(false)
1203 .finish();
1204
1205 inner_object_builder.finish();
1206 }
1207
1208 outer_object_builder.finish();
1209 }
1210
1211 let (metadata, value) = builder.finish();
1212 let variant = Variant::try_new(&metadata, &value).unwrap();
1213 let outer_object = variant.as_object().unwrap();
1214
1215 assert_eq!(outer_object.len(), 1);
1216 assert_eq!(outer_object.field_name(0).unwrap(), "door 1");
1217
1218 let inner_object_variant = outer_object.field(0).unwrap();
1219 let inner_object = inner_object_variant.as_object().unwrap();
1220
1221 assert_eq!(inner_object.len(), 1);
1222 assert_eq!(inner_object.field_name(0).unwrap(), "items");
1223
1224 let items_variant = inner_object.field(0).unwrap();
1225 let items_list = items_variant.as_list().unwrap();
1226
1227 assert_eq!(items_list.len(), 2);
1228 assert_eq!(items_list.get(0).unwrap(), Variant::from("apple"));
1229 assert_eq!(items_list.get(1).unwrap(), Variant::from(false));
1230 }
1231
1232 #[test]
1233 fn test_sorted_dictionary() {
1234 let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"]);
1236
1237 let mut variant2 = {
1238 let mut builder = VariantBuilder::new();
1239
1240 builder.add_field_name("b");
1241 builder.add_field_name("c");
1242 builder.add_field_name("d");
1243
1244 builder
1245 };
1246
1247 assert_eq!(
1248 variant1.metadata_builder.field_names,
1249 variant2.metadata_builder.field_names
1250 );
1251
1252 assert!(variant1.metadata_builder.is_sorted);
1254 assert!(variant2.metadata_builder.is_sorted);
1255
1256 {
1257 variant2.add_field_name("a");
1259 assert!(!variant2.metadata_builder.is_sorted);
1260
1261 let err = variant2.try_finish().unwrap_err();
1263 assert!(err.to_string().contains("empty"), "unexpected error: {err}");
1264 }
1265
1266 variant1.append_value(false);
1268
1269 let (m, v) = variant1.finish();
1270 let res = Variant::try_new(&m, &v);
1271 assert!(res.is_ok());
1272
1273 let header = VariantMetadata::try_new(&m).unwrap();
1274 assert!(header.is_sorted());
1275 }
1276
1277 #[test]
1278 fn test_object_sorted_dictionary() {
1279 let mut variant1 = VariantBuilder::new().with_field_names(["a", "b", "c"]);
1281 let mut obj = variant1.new_object();
1282
1283 obj.insert("c", true);
1284 obj.insert("a", false);
1285 obj.insert("b", ());
1286
1287 let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1289 assert_eq!(field_ids_by_insert_order, vec![2, 0, 1]);
1290
1291 obj.insert("d", 2);
1293 obj.finish();
1294
1295 let (metadata, value) = variant1.finish();
1296 let variant = Variant::try_new(&metadata, &value).unwrap();
1297
1298 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1299 assert!(metadata.is_sorted());
1300
1301 let object = variant.as_object().unwrap();
1303 let field_names = object
1304 .iter()
1305 .map(|(field_name, _)| field_name)
1306 .collect::<Vec<_>>();
1307
1308 assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1309 }
1310
1311 #[test]
1312 fn test_object_not_sorted_dictionary() {
1313 let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"]);
1315 let mut obj = variant1.new_object();
1316
1317 obj.insert("c", true);
1318 obj.insert("d", false);
1319 obj.insert("b", ());
1320
1321 let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1323 assert_eq!(field_ids_by_insert_order, vec![1, 2, 0]);
1324
1325 obj.insert("a", 2);
1327 obj.finish();
1328
1329 let (metadata, value) = variant1.finish();
1330 let variant = Variant::try_new(&metadata, &value).unwrap();
1331
1332 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1333 assert!(!metadata.is_sorted());
1334
1335 let object = variant.as_object().unwrap();
1337 let field_names = object
1338 .iter()
1339 .map(|(field_name, _)| field_name)
1340 .collect::<Vec<_>>();
1341
1342 assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1343 }
1344
1345 #[test]
1346 fn test_building_sorted_dictionary() {
1347 let mut builder = VariantBuilder::new();
1348 assert!(!builder.metadata_builder.is_sorted);
1349 assert_eq!(builder.metadata_builder.num_field_names(), 0);
1350
1351 builder.add_field_name("a");
1352
1353 assert!(builder.metadata_builder.is_sorted);
1354 assert_eq!(builder.metadata_builder.num_field_names(), 1);
1355
1356 let builder = builder.with_field_names(["b", "c", "d"]);
1357
1358 assert!(builder.metadata_builder.is_sorted);
1359 assert_eq!(builder.metadata_builder.num_field_names(), 4);
1360
1361 let builder = builder.with_field_names(["z", "y"]);
1362 assert!(!builder.metadata_builder.is_sorted);
1363 assert_eq!(builder.metadata_builder.num_field_names(), 6);
1364 }
1365
1366 #[test]
1367 fn test_variant_builder_to_list_builder_no_finish() {
1368 let mut builder = VariantBuilder::new();
1370 let mut list_builder = builder.new_list();
1371 list_builder.append_value("hi");
1372 drop(list_builder);
1373
1374 builder.append_value(42i8);
1375
1376 let (metadata, value) = builder.finish();
1378 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1379 assert!(metadata.is_empty());
1380
1381 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1382 assert_eq!(variant, Variant::Int8(42));
1383 }
1384
1385 #[test]
1386 fn test_variant_builder_to_object_builder_no_finish() {
1387 let mut builder = VariantBuilder::new();
1389 let mut object_builder = builder.new_object();
1390 object_builder.insert("name", "unknown");
1391 drop(object_builder);
1392
1393 builder.append_value(42i8);
1394
1395 let (metadata, value) = builder.finish();
1397 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1398 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1401 assert_eq!(variant, Variant::Int8(42));
1402 }
1403
1404 #[test]
1405 fn test_list_builder_to_list_builder_inner_no_finish() {
1406 let mut builder = VariantBuilder::new();
1407 let mut list_builder = builder.new_list();
1408 list_builder.append_value(1i8);
1409
1410 let mut nested_list_builder = list_builder.new_list();
1412 nested_list_builder.append_value("hi");
1413 drop(nested_list_builder);
1414
1415 list_builder.append_value(2i8);
1416
1417 list_builder.finish();
1419 let (metadata, value) = builder.finish();
1420 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1421 assert!(metadata.is_empty());
1422
1423 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1424 let list = variant.as_list().unwrap();
1425 assert_eq!(list.len(), 2);
1426 assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
1427 assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
1428 }
1429
1430 #[test]
1431 fn test_list_builder_to_list_builder_outer_no_finish() {
1432 let mut builder = VariantBuilder::new();
1433 let mut list_builder = builder.new_list();
1434 list_builder.append_value(1i8);
1435
1436 let mut nested_list_builder = list_builder.new_list();
1438 nested_list_builder.append_value("hi");
1439 nested_list_builder.finish();
1440
1441 drop(list_builder);
1443
1444 builder.append_value(2i8);
1445
1446 let (metadata, value) = builder.finish();
1448 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1449 assert!(metadata.is_empty());
1450
1451 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1452 assert_eq!(variant, Variant::Int8(2));
1453 }
1454
1455 #[test]
1456 fn test_list_builder_to_object_builder_inner_no_finish() {
1457 let mut builder = VariantBuilder::new();
1458 let mut list_builder = builder.new_list();
1459 list_builder.append_value(1i8);
1460
1461 let mut nested_object_builder = list_builder.new_object();
1463 nested_object_builder.insert("name", "unknown");
1464 drop(nested_object_builder);
1465
1466 list_builder.append_value(2i8);
1467
1468 list_builder.finish();
1470 let (metadata, value) = builder.finish();
1471 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1472 assert!(metadata.is_empty());
1473
1474 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1475 let list = variant.as_list().unwrap();
1476 assert_eq!(list.len(), 2);
1477 assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
1478 assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
1479 }
1480
1481 #[test]
1482 fn test_list_builder_to_object_builder_outer_no_finish() {
1483 let mut builder = VariantBuilder::new();
1484 let mut list_builder = builder.new_list();
1485 list_builder.append_value(1i8);
1486
1487 let mut nested_object_builder = list_builder.new_object();
1489 nested_object_builder.insert("name", "unknown");
1490 nested_object_builder.finish();
1491
1492 drop(list_builder);
1494
1495 builder.append_value(2i8);
1496
1497 let (metadata, value) = builder.finish();
1499 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1500 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1503 assert_eq!(variant, Variant::Int8(2));
1504 }
1505
1506 #[test]
1507 fn test_object_builder_to_list_builder_inner_no_finish() {
1508 let mut builder = VariantBuilder::new();
1509 let mut object_builder = builder.new_object();
1510 object_builder.insert("first", 1i8);
1511
1512 let mut nested_list_builder = object_builder.new_list("nested");
1514 nested_list_builder.append_value("hi");
1515 drop(nested_list_builder);
1516
1517 object_builder.insert("second", 2i8);
1518
1519 object_builder.finish();
1521 let (metadata, value) = builder.finish();
1522
1523 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1524 assert_eq!(metadata.len(), 2);
1525 assert_eq!(&metadata[0], "first");
1526 assert_eq!(&metadata[1], "second");
1527
1528 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1529 let obj = variant.as_object().unwrap();
1530 assert_eq!(obj.len(), 2);
1531 assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
1532 assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
1533 }
1534
1535 #[test]
1536 fn test_object_builder_to_list_builder_outer_no_finish() {
1537 let mut builder = VariantBuilder::new();
1538 let mut object_builder = builder.new_object();
1539 object_builder.insert("first", 1i8);
1540
1541 let mut nested_list_builder = object_builder.new_list("nested");
1543 nested_list_builder.append_value("hi");
1544 nested_list_builder.finish();
1545
1546 drop(object_builder);
1548
1549 builder.append_value(2i8);
1550
1551 let (metadata, value) = builder.finish();
1553 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1554 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1557 assert_eq!(variant, Variant::Int8(2));
1558 }
1559
1560 #[test]
1561 fn test_object_builder_to_object_builder_inner_no_finish() {
1562 let mut builder = VariantBuilder::new();
1563 let mut object_builder = builder.new_object();
1564 object_builder.insert("first", 1i8);
1565
1566 let mut nested_object_builder = object_builder.new_object("nested");
1568 nested_object_builder.insert("name", "unknown");
1569 drop(nested_object_builder);
1570
1571 object_builder.insert("second", 2i8);
1572
1573 object_builder.finish();
1575 let (metadata, value) = builder.finish();
1576
1577 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1578 assert_eq!(metadata.len(), 2); assert_eq!(&metadata[0], "first");
1580 assert_eq!(&metadata[1], "second");
1581
1582 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1583 let obj = variant.as_object().unwrap();
1584 assert_eq!(obj.len(), 2);
1585 assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
1586 assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
1587 }
1588
1589 #[test]
1590 fn test_object_builder_to_object_builder_outer_no_finish() {
1591 let mut builder = VariantBuilder::new();
1592 let mut object_builder = builder.new_object();
1593 object_builder.insert("first", 1i8);
1594
1595 let mut nested_object_builder = object_builder.new_object("nested");
1597 nested_object_builder.insert("name", "unknown");
1598 nested_object_builder.finish();
1599
1600 drop(object_builder);
1602
1603 builder.append_value(2i8);
1604
1605 let (metadata, value) = builder.finish();
1607 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1608 assert_eq!(metadata.len(), 0); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1611 assert_eq!(variant, Variant::Int8(2));
1612 }
1613
1614 #[test]
1617 fn test_append_list_object_list_object() {
1618 let mut counter = 0..;
1620 let mut take = move |i| (&mut counter).take(i).collect::<Vec<_>>();
1621 let mut builder = VariantBuilder::new();
1622 let skip = 5;
1623 {
1624 let mut list = builder.new_list();
1625 for i in take(4) {
1626 let mut object = list.new_object();
1627 for i in take(4) {
1628 let field_name = format!("field{i}");
1629 let mut list = object.new_list(&field_name);
1630 for i in take(3) {
1631 let mut object = list.new_object();
1632 for i in take(3) {
1633 if i % skip != 0 {
1634 object.insert(&format!("field{i}"), i);
1635 }
1636 }
1637 if i % skip != 0 {
1638 object.finish();
1639 }
1640 }
1641 if i % skip != 0 {
1642 list.finish();
1643 }
1644 }
1645 if i % skip != 0 {
1646 object.finish();
1647 }
1648 }
1649 list.finish();
1650 }
1651 let (metadata, value) = builder.finish();
1652 let v1 = Variant::try_new(&metadata, &value).unwrap();
1653
1654 let (metadata, value) = VariantBuilder::new().with_value(v1.clone()).finish();
1655 let v2 = Variant::try_new(&metadata, &value).unwrap();
1656
1657 assert_eq!(format!("{v1:?}"), format!("{v2:?}"));
1658 }
1659
1660 #[test]
1661 fn test_append_variant_bytes_round_trip() {
1662 let mut builder = VariantBuilder::new();
1664 {
1665 let mut obj = builder.new_object();
1666 obj.insert("name", "Alice");
1667 obj.insert("age", 30i32);
1668 {
1669 let mut scores_list = obj.new_list("scores");
1670 scores_list.append_value(95i32);
1671 scores_list.append_value(87i32);
1672 scores_list.append_value(92i32);
1673 scores_list.finish();
1674 }
1675 {
1676 let mut address = obj.new_object("address");
1677 address.insert("street", "123 Main St");
1678 address.insert("city", "Anytown");
1679 address.finish();
1680 }
1681 obj.finish();
1682 }
1683 let (metadata, value1) = builder.finish();
1684 let variant1 = Variant::try_new(&metadata, &value1).unwrap();
1685
1686 let metadata = VariantMetadata::new(&metadata);
1688 let mut metadata = ReadOnlyMetadataBuilder::new(&metadata);
1689 let mut builder2 = ValueBuilder::new();
1690 let state = ParentState::variant(&mut builder2, &mut metadata);
1691 ValueBuilder::append_variant_bytes(state, variant1);
1692 let value2 = builder2.into_inner();
1693
1694 assert_eq!(value1, value2);
1696 }
1697
1698 #[test]
1699 fn test_object_insert_bytes_subset() {
1700 let mut builder = VariantBuilder::new().with_field_names(["new_field", "another_field"]);
1702 {
1703 let mut obj = builder.new_object();
1704 obj.insert("field1", "value1");
1705 obj.insert("field2", 42i32);
1706 obj.insert("field3", true);
1707 obj.insert("field4", "value4");
1708 obj.finish();
1709 }
1710 let (metadata1, value1) = builder.finish();
1711 let original_variant = Variant::try_new(&metadata1, &value1).unwrap();
1712 let original_obj = original_variant.as_object().unwrap();
1713
1714 let metadata2 = VariantMetadata::new(&metadata1);
1716 let mut metadata2 = ReadOnlyMetadataBuilder::new(&metadata2);
1717 let mut builder2 = ValueBuilder::new();
1718 let state = ParentState::variant(&mut builder2, &mut metadata2);
1719 {
1720 let mut obj = ObjectBuilder::new(state, true);
1721
1722 obj.insert_bytes("field1", original_obj.get("field1").unwrap());
1724
1725 obj.insert("new_field", "new_value");
1727
1728 obj.insert_bytes("field3", original_obj.get("field3").unwrap());
1730
1731 obj.insert("another_field", 99i32);
1733
1734 obj.insert_bytes("field2", original_obj.get("field2").unwrap());
1736
1737 obj.finish();
1738 }
1739 let value2 = builder2.into_inner();
1740 let result_variant = Variant::try_new(&metadata1, &value2).unwrap();
1741 let result_obj = result_variant.as_object().unwrap();
1742
1743 assert_eq!(result_obj.len(), 5);
1745 assert_eq!(
1746 result_obj.get("field1").unwrap().as_string().unwrap(),
1747 "value1"
1748 );
1749 assert_eq!(result_obj.get("field2").unwrap().as_int32().unwrap(), 42);
1750 assert!(result_obj.get("field3").unwrap().as_boolean().unwrap());
1751 assert_eq!(
1752 result_obj.get("new_field").unwrap().as_string().unwrap(),
1753 "new_value"
1754 );
1755 assert_eq!(
1756 result_obj.get("another_field").unwrap().as_int32().unwrap(),
1757 99
1758 );
1759 }
1760
1761 #[test]
1762 fn test_complex_nested_filtering_injection() {
1763 let mut builder = VariantBuilder::new().with_field_names([
1766 "active_count",
1767 "active_users",
1768 "computed_score",
1769 "processed_at",
1770 "status",
1771 ]);
1772
1773 {
1774 let mut root_obj = builder.new_object();
1775 root_obj.insert("metadata", "original");
1776
1777 {
1778 let mut users_list = root_obj.new_list("users");
1779
1780 {
1782 let mut user1 = users_list.new_object();
1783 user1.insert("id", 1i32);
1784 user1.insert("name", "Alice");
1785 user1.insert("active", true);
1786 user1.finish();
1787 }
1788
1789 {
1791 let mut user2 = users_list.new_object();
1792 user2.insert("id", 2i32);
1793 user2.insert("name", "Bob");
1794 user2.insert("active", false);
1795 user2.finish();
1796 }
1797
1798 {
1800 let mut user3 = users_list.new_object();
1801 user3.insert("id", 3i32);
1802 user3.insert("name", "Charlie");
1803 user3.insert("active", true);
1804 user3.finish();
1805 }
1806
1807 users_list.finish();
1808 }
1809
1810 root_obj.insert("total_count", 3i32);
1811 root_obj.finish();
1812 }
1813 let (metadata1, value1) = builder.finish();
1814 let original_variant = Variant::try_new(&metadata1, &value1).unwrap();
1815 let original_obj = original_variant.as_object().unwrap();
1816 let original_users = original_obj.get("users").unwrap();
1817 let original_users = original_users.as_list().unwrap();
1818
1819 let metadata2 = VariantMetadata::new(&metadata1);
1821 let mut metadata2 = ReadOnlyMetadataBuilder::new(&metadata2);
1822 let mut builder2 = ValueBuilder::new();
1823 let state = ParentState::variant(&mut builder2, &mut metadata2);
1824 {
1825 let mut root_obj = ObjectBuilder::new(state, true);
1826
1827 root_obj.insert_bytes("metadata", original_obj.get("metadata").unwrap());
1829
1830 root_obj.insert("processed_at", "2024-01-01T00:00:00Z");
1832
1833 {
1834 let mut filtered_users = root_obj.new_list("active_users");
1835
1836 for i in 0..original_users.len() {
1838 let user = original_users.get(i).unwrap();
1839 let user = user.as_object().unwrap();
1840 if user.get("active").unwrap().as_boolean().unwrap() {
1841 {
1842 let mut new_user = filtered_users.new_object();
1843
1844 new_user.insert_bytes("id", user.get("id").unwrap());
1846 new_user.insert_bytes("name", user.get("name").unwrap());
1847
1848 let user_id = user.get("id").unwrap().as_int32().unwrap();
1850 new_user.insert("computed_score", user_id * 10);
1851
1852 new_user.insert("status", "verified");
1854
1855 new_user.finish();
1856 }
1857 }
1858 }
1859
1860 {
1862 let mut new_user = filtered_users.new_object();
1863 new_user.insert("id", 999i32);
1864 new_user.insert("name", "System User");
1865 new_user.insert("computed_score", 0i32);
1866 new_user.insert("status", "system");
1867 new_user.finish();
1868 }
1869
1870 filtered_users.finish();
1871 }
1872
1873 root_obj.insert("active_count", 3i32); root_obj.finish();
1877 }
1878 let value2 = builder2.into_inner();
1879 let result_variant = Variant::try_new(&metadata1, &value2).unwrap();
1880 let result_obj = result_variant.as_object().unwrap();
1881
1882 assert_eq!(
1884 result_obj.get("metadata").unwrap().as_string().unwrap(),
1885 "original"
1886 );
1887 assert_eq!(
1888 result_obj.get("processed_at").unwrap().as_string().unwrap(),
1889 "2024-01-01T00:00:00Z"
1890 );
1891 assert_eq!(
1892 result_obj.get("active_count").unwrap().as_int32().unwrap(),
1893 3
1894 );
1895
1896 let active_users = result_obj.get("active_users").unwrap();
1897 let active_users = active_users.as_list().unwrap();
1898 assert_eq!(active_users.len(), 3);
1899
1900 let alice = active_users.get(0).unwrap();
1902 let alice = alice.as_object().unwrap();
1903 assert_eq!(alice.get("id").unwrap().as_int32().unwrap(), 1);
1904 assert_eq!(alice.get("name").unwrap().as_string().unwrap(), "Alice");
1905 assert_eq!(alice.get("computed_score").unwrap().as_int32().unwrap(), 10);
1906 assert_eq!(
1907 alice.get("status").unwrap().as_string().unwrap(),
1908 "verified"
1909 );
1910 assert!(alice.get("active").is_none()); let charlie = active_users.get(1).unwrap();
1914 let charlie = charlie.as_object().unwrap();
1915 assert_eq!(charlie.get("id").unwrap().as_int32().unwrap(), 3);
1916 assert_eq!(charlie.get("name").unwrap().as_string().unwrap(), "Charlie");
1917 assert_eq!(
1918 charlie.get("computed_score").unwrap().as_int32().unwrap(),
1919 30
1920 );
1921 assert_eq!(
1922 charlie.get("status").unwrap().as_string().unwrap(),
1923 "verified"
1924 );
1925
1926 let system_user = active_users.get(2).unwrap();
1928 let system_user = system_user.as_object().unwrap();
1929 assert_eq!(system_user.get("id").unwrap().as_int32().unwrap(), 999);
1930 assert_eq!(
1931 system_user.get("name").unwrap().as_string().unwrap(),
1932 "System User"
1933 );
1934 assert_eq!(
1935 system_user
1936 .get("computed_score")
1937 .unwrap()
1938 .as_int32()
1939 .unwrap(),
1940 0
1941 );
1942 assert_eq!(
1943 system_user.get("status").unwrap().as_string().unwrap(),
1944 "system"
1945 );
1946 }
1947}