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
55#[derive(Debug, Default)]
63pub struct ValueBuilder(Vec<u8>);
64
65impl ValueBuilder {
66 pub fn new() -> Self {
68 Default::default()
69 }
70}
71
72macro_rules! variant_append_value {
75 ($builder:expr, $value:expr, $object_pat:pat => $object_arm:expr, $list_pat:pat => $list_arm:expr) => {
76 match $value {
77 Variant::Null => $builder.append_null(),
78 Variant::BooleanTrue => $builder.append_bool(true),
79 Variant::BooleanFalse => $builder.append_bool(false),
80 Variant::Int8(v) => $builder.append_int8(v),
81 Variant::Int16(v) => $builder.append_int16(v),
82 Variant::Int32(v) => $builder.append_int32(v),
83 Variant::Int64(v) => $builder.append_int64(v),
84 Variant::Date(v) => $builder.append_date(v),
85 Variant::Time(v) => $builder.append_time_micros(v),
86 Variant::TimestampMicros(v) => $builder.append_timestamp_micros(v),
87 Variant::TimestampNtzMicros(v) => $builder.append_timestamp_ntz_micros(v),
88 Variant::TimestampNanos(v) => $builder.append_timestamp_nanos(v),
89 Variant::TimestampNtzNanos(v) => $builder.append_timestamp_ntz_nanos(v),
90 Variant::Decimal4(decimal4) => $builder.append_decimal4(decimal4),
91 Variant::Decimal8(decimal8) => $builder.append_decimal8(decimal8),
92 Variant::Decimal16(decimal16) => $builder.append_decimal16(decimal16),
93 Variant::Float(v) => $builder.append_float(v),
94 Variant::Double(v) => $builder.append_double(v),
95 Variant::Binary(v) => $builder.append_binary(v),
96 Variant::String(s) => $builder.append_string(s),
97 Variant::ShortString(s) => $builder.append_short_string(s),
98 Variant::Uuid(v) => $builder.append_uuid(v),
99 $object_pat => $object_arm,
100 $list_pat => $list_arm,
101 }
102 };
103}
104
105impl ValueBuilder {
106 fn append_u8(&mut self, term: u8) {
107 self.0.push(term);
108 }
109
110 fn append_slice(&mut self, other: &[u8]) {
111 self.0.extend_from_slice(other);
112 }
113
114 fn append_primitive_header(&mut self, primitive_type: VariantPrimitiveType) {
115 self.0.push(primitive_header(primitive_type));
116 }
117
118 pub fn into_inner(self) -> Vec<u8> {
120 self.0
121 }
122
123 pub(crate) fn inner_mut(&mut self) -> &mut Vec<u8> {
124 &mut self.0
125 }
126
127 fn append_null(&mut self) {
130 self.append_primitive_header(VariantPrimitiveType::Null);
131 }
132
133 fn append_bool(&mut self, value: bool) {
134 let primitive_type = if value {
135 VariantPrimitiveType::BooleanTrue
136 } else {
137 VariantPrimitiveType::BooleanFalse
138 };
139 self.append_primitive_header(primitive_type);
140 }
141
142 fn append_int8(&mut self, value: i8) {
143 self.append_primitive_header(VariantPrimitiveType::Int8);
144 self.append_u8(value as u8);
145 }
146
147 fn append_int16(&mut self, value: i16) {
148 self.append_primitive_header(VariantPrimitiveType::Int16);
149 self.append_slice(&value.to_le_bytes());
150 }
151
152 fn append_int32(&mut self, value: i32) {
153 self.append_primitive_header(VariantPrimitiveType::Int32);
154 self.append_slice(&value.to_le_bytes());
155 }
156
157 fn append_int64(&mut self, value: i64) {
158 self.append_primitive_header(VariantPrimitiveType::Int64);
159 self.append_slice(&value.to_le_bytes());
160 }
161
162 fn append_float(&mut self, value: f32) {
163 self.append_primitive_header(VariantPrimitiveType::Float);
164 self.append_slice(&value.to_le_bytes());
165 }
166
167 fn append_double(&mut self, value: f64) {
168 self.append_primitive_header(VariantPrimitiveType::Double);
169 self.append_slice(&value.to_le_bytes());
170 }
171
172 fn append_date(&mut self, value: chrono::NaiveDate) {
173 self.append_primitive_header(VariantPrimitiveType::Date);
174 let days_since_epoch = value.signed_duration_since(UNIX_EPOCH_DATE).num_days() as i32;
175 self.append_slice(&days_since_epoch.to_le_bytes());
176 }
177
178 fn append_timestamp_micros(&mut self, value: chrono::DateTime<chrono::Utc>) {
179 self.append_primitive_header(VariantPrimitiveType::TimestampMicros);
180 let micros = value.timestamp_micros();
181 self.append_slice(µs.to_le_bytes());
182 }
183
184 fn append_timestamp_ntz_micros(&mut self, value: chrono::NaiveDateTime) {
185 self.append_primitive_header(VariantPrimitiveType::TimestampNtzMicros);
186 let micros = value.and_utc().timestamp_micros();
187 self.append_slice(µs.to_le_bytes());
188 }
189
190 fn append_time_micros(&mut self, value: chrono::NaiveTime) {
191 self.append_primitive_header(VariantPrimitiveType::Time);
192 let micros_from_midnight = value.num_seconds_from_midnight() as u64 * 1_000_000
193 + value.nanosecond() as u64 / 1_000;
194 self.append_slice(µs_from_midnight.to_le_bytes());
195 }
196
197 fn append_timestamp_nanos(&mut self, value: chrono::DateTime<chrono::Utc>) {
198 self.append_primitive_header(VariantPrimitiveType::TimestampNanos);
199 let nanos = value.timestamp_nanos_opt().unwrap();
200 self.append_slice(&nanos.to_le_bytes());
201 }
202
203 fn append_timestamp_ntz_nanos(&mut self, value: chrono::NaiveDateTime) {
204 self.append_primitive_header(VariantPrimitiveType::TimestampNtzNanos);
205 let nanos = value.and_utc().timestamp_nanos_opt().unwrap();
206 self.append_slice(&nanos.to_le_bytes());
207 }
208
209 fn append_uuid(&mut self, value: Uuid) {
210 self.append_primitive_header(VariantPrimitiveType::Uuid);
211 self.append_slice(&value.into_bytes());
212 }
213
214 fn append_decimal4(&mut self, decimal4: VariantDecimal4) {
215 self.append_primitive_header(VariantPrimitiveType::Decimal4);
216 self.append_u8(decimal4.scale());
217 self.append_slice(&decimal4.integer().to_le_bytes());
218 }
219
220 fn append_decimal8(&mut self, decimal8: VariantDecimal8) {
221 self.append_primitive_header(VariantPrimitiveType::Decimal8);
222 self.append_u8(decimal8.scale());
223 self.append_slice(&decimal8.integer().to_le_bytes());
224 }
225
226 fn append_decimal16(&mut self, decimal16: VariantDecimal16) {
227 self.append_primitive_header(VariantPrimitiveType::Decimal16);
228 self.append_u8(decimal16.scale());
229 self.append_slice(&decimal16.integer().to_le_bytes());
230 }
231
232 fn append_binary(&mut self, value: &[u8]) {
233 self.append_primitive_header(VariantPrimitiveType::Binary);
234 self.append_slice(&(value.len() as u32).to_le_bytes());
235 self.append_slice(value);
236 }
237
238 fn append_short_string(&mut self, value: ShortString) {
239 let inner = value.0;
240 self.append_u8(short_string_header(inner.len()));
241 self.append_slice(inner.as_bytes());
242 }
243
244 fn append_string(&mut self, value: &str) {
245 self.append_primitive_header(VariantPrimitiveType::String);
246 self.append_slice(&(value.len() as u32).to_le_bytes());
247 self.append_slice(value.as_bytes());
248 }
249
250 fn append_object<S: BuilderSpecificState>(state: ParentState<'_, S>, obj: VariantObject) {
251 let mut object_builder = ObjectBuilder::new(state, false);
252 object_builder.extend(obj.iter());
253 object_builder.finish();
254 }
255
256 fn try_append_object<S: BuilderSpecificState>(
257 state: ParentState<'_, S>,
258 obj: VariantObject,
259 ) -> Result<(), ArrowError> {
260 let mut object_builder = ObjectBuilder::new(state, false);
261
262 for res in obj.iter_try() {
263 let (field_name, value) = res?;
264 object_builder.try_insert(field_name, value)?;
265 }
266
267 object_builder.finish();
268 Ok(())
269 }
270
271 fn append_list<S: BuilderSpecificState>(state: ParentState<'_, S>, list: VariantList) {
272 let mut list_builder = ListBuilder::new(state, false);
273 list_builder.extend(list.iter());
274 list_builder.finish();
275 }
276
277 fn try_append_list<S: BuilderSpecificState>(
278 state: ParentState<'_, S>,
279 list: VariantList,
280 ) -> Result<(), ArrowError> {
281 let mut list_builder = ListBuilder::new(state, false);
282 for res in list.iter_try() {
283 let value = res?;
284 list_builder.try_append_value(value)?;
285 }
286
287 list_builder.finish();
288
289 Ok(())
290 }
291
292 pub fn offset(&self) -> usize {
294 self.0.len()
295 }
296
297 pub fn append_variant<S: BuilderSpecificState>(
304 mut state: ParentState<'_, S>,
305 variant: Variant<'_, '_>,
306 ) {
307 variant_append_value!(
308 state.value_builder(),
309 variant,
310 Variant::Object(obj) => return Self::append_object(state, obj),
311 Variant::List(list) => return Self::append_list(state, list)
312 );
313 state.finish();
314 }
315
316 pub fn try_append_variant<S: BuilderSpecificState>(
321 mut state: ParentState<'_, S>,
322 variant: Variant<'_, '_>,
323 ) -> Result<(), ArrowError> {
324 variant_append_value!(
325 state.value_builder(),
326 variant,
327 Variant::Object(obj) => return Self::try_append_object(state, obj),
328 Variant::List(list) => return Self::try_append_list(state, list)
329 );
330 state.finish();
331 Ok(())
332 }
333
334 pub fn append_variant_bytes<S: BuilderSpecificState>(
343 mut state: ParentState<'_, S>,
344 variant: Variant<'_, '_>,
345 ) {
346 let builder = state.value_builder();
347 variant_append_value!(
348 builder,
349 variant,
350 Variant::Object(obj) => builder.append_slice(obj.value),
351 Variant::List(list) => builder.append_slice(list.value)
352 );
353 state.finish();
354 }
355}
356
357pub trait BuilderSpecificState: std::fmt::Debug {
359 fn finish(
367 &mut self,
368 _metadata_builder: &mut dyn MetadataBuilder,
369 _value_builder: &mut ValueBuilder,
370 ) {
371 }
372
373 fn rollback(&mut self) {}
381}
382
383impl BuilderSpecificState for () {}
385
386#[derive(Debug)]
398pub struct ParentState<'a, S: BuilderSpecificState> {
399 pub(crate) value_builder: &'a mut ValueBuilder,
400 pub(crate) saved_value_builder_offset: usize,
401 pub(crate) metadata_builder: &'a mut dyn MetadataBuilder,
402 pub(crate) saved_metadata_builder_dict_size: usize,
403 pub(crate) builder_state: S,
404 pub(crate) finished: bool,
405}
406
407impl<'a, S: BuilderSpecificState> ParentState<'a, S> {
408 pub fn new(
412 value_builder: &'a mut ValueBuilder,
413 metadata_builder: &'a mut dyn MetadataBuilder,
414 builder_state: S,
415 ) -> Self {
416 Self {
417 saved_value_builder_offset: value_builder.offset(),
418 value_builder,
419 saved_metadata_builder_dict_size: metadata_builder.num_field_names(),
420 metadata_builder,
421 builder_state,
422 finished: false,
423 }
424 }
425
426 pub fn finish(&mut self) {
429 self.builder_state
430 .finish(self.metadata_builder, self.value_builder);
431 self.finished = true
432 }
433
434 fn rollback(&mut self) {
436 if self.finished {
437 return;
438 }
439
440 self.value_builder
441 .inner_mut()
442 .truncate(self.saved_value_builder_offset);
443 self.metadata_builder
444 .truncate_field_names(self.saved_metadata_builder_dict_size);
445 self.builder_state.rollback();
446 }
447
448 pub(crate) fn value_builder(&mut self) -> &mut ValueBuilder {
450 self.value_builder
451 }
452
453 pub(crate) fn metadata_builder(&mut self) -> &mut dyn MetadataBuilder {
455 self.metadata_builder
456 }
457}
458
459impl<'a> ParentState<'a, ()> {
460 pub fn variant(
464 value_builder: &'a mut ValueBuilder,
465 metadata_builder: &'a mut dyn MetadataBuilder,
466 ) -> Self {
467 Self::new(value_builder, metadata_builder, ())
468 }
469}
470
471impl<S: BuilderSpecificState> Drop for ParentState<'_, S> {
473 fn drop(&mut self) {
474 self.rollback()
475 }
476}
477
478#[derive(Default, Debug)]
714pub struct VariantBuilder {
715 value_builder: ValueBuilder,
716 metadata_builder: WritableMetadataBuilder,
717 validate_unique_fields: bool,
718}
719
720impl VariantBuilder {
721 pub fn new() -> Self {
723 Self {
724 value_builder: ValueBuilder::new(),
725 metadata_builder: WritableMetadataBuilder::default(),
726 validate_unique_fields: false,
727 }
728 }
729
730 pub fn with_metadata(mut self, metadata: VariantMetadata) -> Self {
732 self.metadata_builder.extend(metadata.iter());
733
734 self
735 }
736
737 pub fn with_validate_unique_fields(mut self, validate_unique_fields: bool) -> Self {
743 self.validate_unique_fields = validate_unique_fields;
744 self
745 }
746
747 pub fn with_field_names<'a>(mut self, field_names: impl IntoIterator<Item = &'a str>) -> Self {
754 self.metadata_builder.extend(field_names);
755
756 self
757 }
758
759 pub fn with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(mut self, value: T) -> Self {
766 self.append_value(value);
767 self
768 }
769
770 pub fn try_with_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
774 mut self,
775 value: T,
776 ) -> Result<Self, ArrowError> {
777 self.try_append_value(value)?;
778 Ok(self)
779 }
780
781 pub fn reserve(&mut self, capacity: usize) {
785 self.metadata_builder.field_names.reserve(capacity);
786 }
787
788 pub fn add_field_name(&mut self, field_name: &str) {
792 self.metadata_builder.upsert_field_name(field_name);
793 }
794
795 pub fn new_list(&mut self) -> ListBuilder<'_, ()> {
799 let parent_state =
800 ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
801 ListBuilder::new(parent_state, self.validate_unique_fields)
802 }
803
804 pub fn new_object(&mut self) -> ObjectBuilder<'_, ()> {
808 let parent_state =
809 ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
810 ObjectBuilder::new(parent_state, self.validate_unique_fields)
811 }
812
813 pub fn append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(&mut self, value: T) {
828 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
829 ValueBuilder::append_variant(state, value.into())
830 }
831
832 pub fn try_append_value<'m, 'd, T: Into<Variant<'m, 'd>>>(
834 &mut self,
835 value: T,
836 ) -> Result<(), ArrowError> {
837 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
838 ValueBuilder::try_append_variant(state, value.into())
839 }
840
841 pub fn append_value_bytes<'m, 'd>(&mut self, value: impl Into<Variant<'m, 'd>>) {
850 let state = ParentState::variant(&mut self.value_builder, &mut self.metadata_builder);
851 ValueBuilder::append_variant_bytes(state, value.into());
852 }
853
854 pub fn finish(mut self) -> (Vec<u8>, Vec<u8>) {
856 self.metadata_builder.finish();
857 (
858 self.metadata_builder.into_inner(),
859 self.value_builder.into_inner(),
860 )
861 }
862}
863
864pub trait VariantBuilderExt {
869 type State<'a>: BuilderSpecificState + 'a
871 where
872 Self: 'a;
873
874 fn append_null(&mut self);
877
878 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>);
880
881 fn new_list(&mut self) -> ListBuilder<'_, Self::State<'_>> {
884 self.try_new_list().unwrap()
885 }
886
887 fn new_object(&mut self) -> ObjectBuilder<'_, Self::State<'_>> {
890 self.try_new_object().unwrap()
891 }
892
893 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError>;
896
897 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError>;
900}
901
902impl VariantBuilderExt for VariantBuilder {
903 type State<'a>
904 = ()
905 where
906 Self: 'a;
907
908 fn append_null(&mut self) {
911 self.append_value(Variant::Null);
912 }
913 fn append_value<'m, 'v>(&mut self, value: impl Into<Variant<'m, 'v>>) {
914 self.append_value(value);
915 }
916
917 fn try_new_list(&mut self) -> Result<ListBuilder<'_, Self::State<'_>>, ArrowError> {
918 Ok(self.new_list())
919 }
920
921 fn try_new_object(&mut self) -> Result<ObjectBuilder<'_, Self::State<'_>>, ArrowError> {
922 Ok(self.new_object())
923 }
924}
925
926#[cfg(test)]
927mod tests {
928 use crate::{VariantMetadata, builder::metadata::ReadOnlyMetadataBuilder};
929
930 use super::*;
931 #[test]
932 fn test_simple_usage() {
933 test_variant_roundtrip((), Variant::Null);
934 test_variant_roundtrip(true, Variant::BooleanTrue);
935 test_variant_roundtrip(false, Variant::BooleanFalse);
936 test_variant_roundtrip(42i8, Variant::Int8(42));
937 test_variant_roundtrip(1234i16, Variant::Int16(1234));
938 test_variant_roundtrip(123456i32, Variant::Int32(123456));
939 test_variant_roundtrip(123456789i64, Variant::Int64(123456789));
940 test_variant_roundtrip(1.5f32, Variant::Float(1.5));
941 test_variant_roundtrip(2.5f64, Variant::Double(2.5));
942 test_variant_roundtrip("hello", Variant::ShortString(ShortString("hello")));
943
944 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";
946 test_variant_roundtrip(long_string, Variant::String(long_string));
947
948 let binary_data = b"binary data";
950 test_variant_roundtrip(
951 binary_data.as_slice(),
952 Variant::Binary(binary_data.as_slice()),
953 );
954 }
955
956 fn test_variant_roundtrip<'m, 'd, T: Into<Variant<'m, 'd>>>(input: T, expected: Variant) {
958 let mut builder = VariantBuilder::new();
959 builder.append_value(input);
960 let (metadata, value) = builder.finish();
961 let variant = Variant::try_new(&metadata, &value).unwrap_or_else(|_| {
962 panic!("Failed to create variant from metadata and value: {metadata:?}, {value:?}")
963 });
964 assert_eq!(variant, expected);
965 }
966
967 #[test]
968 fn test_nested_object_with_lists() {
969 let mut builder = VariantBuilder::new();
979 {
980 let mut outer_object_builder = builder.new_object();
981 {
982 let mut inner_object_builder = outer_object_builder.new_object("door 1");
983
984 inner_object_builder
986 .new_list("items")
987 .with_value("apple")
988 .with_value(false)
989 .finish();
990
991 inner_object_builder.finish();
992 }
993
994 outer_object_builder.finish();
995 }
996
997 let (metadata, value) = builder.finish();
998 let variant = Variant::try_new(&metadata, &value).unwrap();
999 let outer_object = variant.as_object().unwrap();
1000
1001 assert_eq!(outer_object.len(), 1);
1002 assert_eq!(outer_object.field_name(0).unwrap(), "door 1");
1003
1004 let inner_object_variant = outer_object.field(0).unwrap();
1005 let inner_object = inner_object_variant.as_object().unwrap();
1006
1007 assert_eq!(inner_object.len(), 1);
1008 assert_eq!(inner_object.field_name(0).unwrap(), "items");
1009
1010 let items_variant = inner_object.field(0).unwrap();
1011 let items_list = items_variant.as_list().unwrap();
1012
1013 assert_eq!(items_list.len(), 2);
1014 assert_eq!(items_list.get(0).unwrap(), Variant::from("apple"));
1015 assert_eq!(items_list.get(1).unwrap(), Variant::from(false));
1016 }
1017
1018 #[test]
1019 fn test_sorted_dictionary() {
1020 let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"]);
1022
1023 let mut variant2 = {
1024 let mut builder = VariantBuilder::new();
1025
1026 builder.add_field_name("b");
1027 builder.add_field_name("c");
1028 builder.add_field_name("d");
1029
1030 builder
1031 };
1032
1033 assert_eq!(
1034 variant1.metadata_builder.field_names,
1035 variant2.metadata_builder.field_names
1036 );
1037
1038 assert!(variant1.metadata_builder.is_sorted);
1040 assert!(variant2.metadata_builder.is_sorted);
1041
1042 {
1043 variant2.add_field_name("a");
1045 assert!(!variant2.metadata_builder.is_sorted);
1046
1047 let (m, v) = variant2.finish();
1049 let res = Variant::try_new(&m, &v);
1050 assert!(res.is_err());
1051
1052 let header = VariantMetadata::try_new(&m).unwrap();
1054 assert!(!header.is_sorted());
1055 }
1056
1057 variant1.append_value(false);
1059
1060 let (m, v) = variant1.finish();
1061 let res = Variant::try_new(&m, &v);
1062 assert!(res.is_ok());
1063
1064 let header = VariantMetadata::try_new(&m).unwrap();
1065 assert!(header.is_sorted());
1066 }
1067
1068 #[test]
1069 fn test_object_sorted_dictionary() {
1070 let mut variant1 = VariantBuilder::new().with_field_names(["a", "b", "c"]);
1072 let mut obj = variant1.new_object();
1073
1074 obj.insert("c", true);
1075 obj.insert("a", false);
1076 obj.insert("b", ());
1077
1078 let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1080 assert_eq!(field_ids_by_insert_order, vec![2, 0, 1]);
1081
1082 obj.insert("d", 2);
1084 obj.finish();
1085
1086 let (metadata, value) = variant1.finish();
1087 let variant = Variant::try_new(&metadata, &value).unwrap();
1088
1089 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1090 assert!(metadata.is_sorted());
1091
1092 let object = variant.as_object().unwrap();
1094 let field_names = object
1095 .iter()
1096 .map(|(field_name, _)| field_name)
1097 .collect::<Vec<_>>();
1098
1099 assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1100 }
1101
1102 #[test]
1103 fn test_object_not_sorted_dictionary() {
1104 let mut variant1 = VariantBuilder::new().with_field_names(["b", "c", "d"]);
1106 let mut obj = variant1.new_object();
1107
1108 obj.insert("c", true);
1109 obj.insert("d", false);
1110 obj.insert("b", ());
1111
1112 let field_ids_by_insert_order = obj.fields.iter().map(|(&id, _)| id).collect::<Vec<_>>();
1114 assert_eq!(field_ids_by_insert_order, vec![1, 2, 0]);
1115
1116 obj.insert("a", 2);
1118 obj.finish();
1119
1120 let (metadata, value) = variant1.finish();
1121 let variant = Variant::try_new(&metadata, &value).unwrap();
1122
1123 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1124 assert!(!metadata.is_sorted());
1125
1126 let object = variant.as_object().unwrap();
1128 let field_names = object
1129 .iter()
1130 .map(|(field_name, _)| field_name)
1131 .collect::<Vec<_>>();
1132
1133 assert_eq!(field_names, vec!["a", "b", "c", "d"]);
1134 }
1135
1136 #[test]
1137 fn test_building_sorted_dictionary() {
1138 let mut builder = VariantBuilder::new();
1139 assert!(!builder.metadata_builder.is_sorted);
1140 assert_eq!(builder.metadata_builder.num_field_names(), 0);
1141
1142 builder.add_field_name("a");
1143
1144 assert!(builder.metadata_builder.is_sorted);
1145 assert_eq!(builder.metadata_builder.num_field_names(), 1);
1146
1147 let builder = builder.with_field_names(["b", "c", "d"]);
1148
1149 assert!(builder.metadata_builder.is_sorted);
1150 assert_eq!(builder.metadata_builder.num_field_names(), 4);
1151
1152 let builder = builder.with_field_names(["z", "y"]);
1153 assert!(!builder.metadata_builder.is_sorted);
1154 assert_eq!(builder.metadata_builder.num_field_names(), 6);
1155 }
1156
1157 #[test]
1158 fn test_variant_builder_to_list_builder_no_finish() {
1159 let mut builder = VariantBuilder::new();
1161 let mut list_builder = builder.new_list();
1162 list_builder.append_value("hi");
1163 drop(list_builder);
1164
1165 builder.append_value(42i8);
1166
1167 let (metadata, value) = builder.finish();
1169 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1170 assert!(metadata.is_empty());
1171
1172 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1173 assert_eq!(variant, Variant::Int8(42));
1174 }
1175
1176 #[test]
1177 fn test_variant_builder_to_object_builder_no_finish() {
1178 let mut builder = VariantBuilder::new();
1180 let mut object_builder = builder.new_object();
1181 object_builder.insert("name", "unknown");
1182 drop(object_builder);
1183
1184 builder.append_value(42i8);
1185
1186 let (metadata, value) = builder.finish();
1188 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1189 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1192 assert_eq!(variant, Variant::Int8(42));
1193 }
1194
1195 #[test]
1196 fn test_list_builder_to_list_builder_inner_no_finish() {
1197 let mut builder = VariantBuilder::new();
1198 let mut list_builder = builder.new_list();
1199 list_builder.append_value(1i8);
1200
1201 let mut nested_list_builder = list_builder.new_list();
1203 nested_list_builder.append_value("hi");
1204 drop(nested_list_builder);
1205
1206 list_builder.append_value(2i8);
1207
1208 list_builder.finish();
1210 let (metadata, value) = builder.finish();
1211 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1212 assert!(metadata.is_empty());
1213
1214 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1215 let list = variant.as_list().unwrap();
1216 assert_eq!(list.len(), 2);
1217 assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
1218 assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
1219 }
1220
1221 #[test]
1222 fn test_list_builder_to_list_builder_outer_no_finish() {
1223 let mut builder = VariantBuilder::new();
1224 let mut list_builder = builder.new_list();
1225 list_builder.append_value(1i8);
1226
1227 let mut nested_list_builder = list_builder.new_list();
1229 nested_list_builder.append_value("hi");
1230 nested_list_builder.finish();
1231
1232 drop(list_builder);
1234
1235 builder.append_value(2i8);
1236
1237 let (metadata, value) = builder.finish();
1239 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1240 assert!(metadata.is_empty());
1241
1242 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1243 assert_eq!(variant, Variant::Int8(2));
1244 }
1245
1246 #[test]
1247 fn test_list_builder_to_object_builder_inner_no_finish() {
1248 let mut builder = VariantBuilder::new();
1249 let mut list_builder = builder.new_list();
1250 list_builder.append_value(1i8);
1251
1252 let mut nested_object_builder = list_builder.new_object();
1254 nested_object_builder.insert("name", "unknown");
1255 drop(nested_object_builder);
1256
1257 list_builder.append_value(2i8);
1258
1259 list_builder.finish();
1261 let (metadata, value) = builder.finish();
1262 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1263 assert!(metadata.is_empty());
1264
1265 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1266 let list = variant.as_list().unwrap();
1267 assert_eq!(list.len(), 2);
1268 assert_eq!(list.get(0).unwrap(), Variant::Int8(1));
1269 assert_eq!(list.get(1).unwrap(), Variant::Int8(2));
1270 }
1271
1272 #[test]
1273 fn test_list_builder_to_object_builder_outer_no_finish() {
1274 let mut builder = VariantBuilder::new();
1275 let mut list_builder = builder.new_list();
1276 list_builder.append_value(1i8);
1277
1278 let mut nested_object_builder = list_builder.new_object();
1280 nested_object_builder.insert("name", "unknown");
1281 nested_object_builder.finish();
1282
1283 drop(list_builder);
1285
1286 builder.append_value(2i8);
1287
1288 let (metadata, value) = builder.finish();
1290 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1291 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1294 assert_eq!(variant, Variant::Int8(2));
1295 }
1296
1297 #[test]
1298 fn test_object_builder_to_list_builder_inner_no_finish() {
1299 let mut builder = VariantBuilder::new();
1300 let mut object_builder = builder.new_object();
1301 object_builder.insert("first", 1i8);
1302
1303 let mut nested_list_builder = object_builder.new_list("nested");
1305 nested_list_builder.append_value("hi");
1306 drop(nested_list_builder);
1307
1308 object_builder.insert("second", 2i8);
1309
1310 object_builder.finish();
1312 let (metadata, value) = builder.finish();
1313
1314 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1315 assert_eq!(metadata.len(), 2);
1316 assert_eq!(&metadata[0], "first");
1317 assert_eq!(&metadata[1], "second");
1318
1319 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1320 let obj = variant.as_object().unwrap();
1321 assert_eq!(obj.len(), 2);
1322 assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
1323 assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
1324 }
1325
1326 #[test]
1327 fn test_object_builder_to_list_builder_outer_no_finish() {
1328 let mut builder = VariantBuilder::new();
1329 let mut object_builder = builder.new_object();
1330 object_builder.insert("first", 1i8);
1331
1332 let mut nested_list_builder = object_builder.new_list("nested");
1334 nested_list_builder.append_value("hi");
1335 nested_list_builder.finish();
1336
1337 drop(object_builder);
1339
1340 builder.append_value(2i8);
1341
1342 let (metadata, value) = builder.finish();
1344 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1345 assert!(metadata.is_empty()); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1348 assert_eq!(variant, Variant::Int8(2));
1349 }
1350
1351 #[test]
1352 fn test_object_builder_to_object_builder_inner_no_finish() {
1353 let mut builder = VariantBuilder::new();
1354 let mut object_builder = builder.new_object();
1355 object_builder.insert("first", 1i8);
1356
1357 let mut nested_object_builder = object_builder.new_object("nested");
1359 nested_object_builder.insert("name", "unknown");
1360 drop(nested_object_builder);
1361
1362 object_builder.insert("second", 2i8);
1363
1364 object_builder.finish();
1366 let (metadata, value) = builder.finish();
1367
1368 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1369 assert_eq!(metadata.len(), 2); assert_eq!(&metadata[0], "first");
1371 assert_eq!(&metadata[1], "second");
1372
1373 let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1374 let obj = variant.as_object().unwrap();
1375 assert_eq!(obj.len(), 2);
1376 assert_eq!(obj.get("first"), Some(Variant::Int8(1)));
1377 assert_eq!(obj.get("second"), Some(Variant::Int8(2)));
1378 }
1379
1380 #[test]
1381 fn test_object_builder_to_object_builder_outer_no_finish() {
1382 let mut builder = VariantBuilder::new();
1383 let mut object_builder = builder.new_object();
1384 object_builder.insert("first", 1i8);
1385
1386 let mut nested_object_builder = object_builder.new_object("nested");
1388 nested_object_builder.insert("name", "unknown");
1389 nested_object_builder.finish();
1390
1391 drop(object_builder);
1393
1394 builder.append_value(2i8);
1395
1396 let (metadata, value) = builder.finish();
1398 let metadata = VariantMetadata::try_new(&metadata).unwrap();
1399 assert_eq!(metadata.len(), 0); let variant = Variant::try_new_with_metadata(metadata, &value).unwrap();
1402 assert_eq!(variant, Variant::Int8(2));
1403 }
1404
1405 #[test]
1408 fn test_append_list_object_list_object() {
1409 let mut counter = 0..;
1411 let mut take = move |i| (&mut counter).take(i).collect::<Vec<_>>();
1412 let mut builder = VariantBuilder::new();
1413 let skip = 5;
1414 {
1415 let mut list = builder.new_list();
1416 for i in take(4) {
1417 let mut object = list.new_object();
1418 for i in take(4) {
1419 let field_name = format!("field{i}");
1420 let mut list = object.new_list(&field_name);
1421 for i in take(3) {
1422 let mut object = list.new_object();
1423 for i in take(3) {
1424 if i % skip != 0 {
1425 object.insert(&format!("field{i}"), i);
1426 }
1427 }
1428 if i % skip != 0 {
1429 object.finish();
1430 }
1431 }
1432 if i % skip != 0 {
1433 list.finish();
1434 }
1435 }
1436 if i % skip != 0 {
1437 object.finish();
1438 }
1439 }
1440 list.finish();
1441 }
1442 let (metadata, value) = builder.finish();
1443 let v1 = Variant::try_new(&metadata, &value).unwrap();
1444
1445 let (metadata, value) = VariantBuilder::new().with_value(v1.clone()).finish();
1446 let v2 = Variant::try_new(&metadata, &value).unwrap();
1447
1448 assert_eq!(format!("{v1:?}"), format!("{v2:?}"));
1449 }
1450
1451 #[test]
1452 fn test_append_variant_bytes_round_trip() {
1453 let mut builder = VariantBuilder::new();
1455 {
1456 let mut obj = builder.new_object();
1457 obj.insert("name", "Alice");
1458 obj.insert("age", 30i32);
1459 {
1460 let mut scores_list = obj.new_list("scores");
1461 scores_list.append_value(95i32);
1462 scores_list.append_value(87i32);
1463 scores_list.append_value(92i32);
1464 scores_list.finish();
1465 }
1466 {
1467 let mut address = obj.new_object("address");
1468 address.insert("street", "123 Main St");
1469 address.insert("city", "Anytown");
1470 address.finish();
1471 }
1472 obj.finish();
1473 }
1474 let (metadata, value1) = builder.finish();
1475 let variant1 = Variant::try_new(&metadata, &value1).unwrap();
1476
1477 let metadata = VariantMetadata::new(&metadata);
1479 let mut metadata = ReadOnlyMetadataBuilder::new(&metadata);
1480 let mut builder2 = ValueBuilder::new();
1481 let state = ParentState::variant(&mut builder2, &mut metadata);
1482 ValueBuilder::append_variant_bytes(state, variant1);
1483 let value2 = builder2.into_inner();
1484
1485 assert_eq!(value1, value2);
1487 }
1488
1489 #[test]
1490 fn test_object_insert_bytes_subset() {
1491 let mut builder = VariantBuilder::new().with_field_names(["new_field", "another_field"]);
1493 {
1494 let mut obj = builder.new_object();
1495 obj.insert("field1", "value1");
1496 obj.insert("field2", 42i32);
1497 obj.insert("field3", true);
1498 obj.insert("field4", "value4");
1499 obj.finish();
1500 }
1501 let (metadata1, value1) = builder.finish();
1502 let original_variant = Variant::try_new(&metadata1, &value1).unwrap();
1503 let original_obj = original_variant.as_object().unwrap();
1504
1505 let metadata2 = VariantMetadata::new(&metadata1);
1507 let mut metadata2 = ReadOnlyMetadataBuilder::new(&metadata2);
1508 let mut builder2 = ValueBuilder::new();
1509 let state = ParentState::variant(&mut builder2, &mut metadata2);
1510 {
1511 let mut obj = ObjectBuilder::new(state, true);
1512
1513 obj.insert_bytes("field1", original_obj.get("field1").unwrap());
1515
1516 obj.insert("new_field", "new_value");
1518
1519 obj.insert_bytes("field3", original_obj.get("field3").unwrap());
1521
1522 obj.insert("another_field", 99i32);
1524
1525 obj.insert_bytes("field2", original_obj.get("field2").unwrap());
1527
1528 obj.finish();
1529 }
1530 let value2 = builder2.into_inner();
1531 let result_variant = Variant::try_new(&metadata1, &value2).unwrap();
1532 let result_obj = result_variant.as_object().unwrap();
1533
1534 assert_eq!(result_obj.len(), 5);
1536 assert_eq!(
1537 result_obj.get("field1").unwrap().as_string().unwrap(),
1538 "value1"
1539 );
1540 assert_eq!(result_obj.get("field2").unwrap().as_int32().unwrap(), 42);
1541 assert!(result_obj.get("field3").unwrap().as_boolean().unwrap());
1542 assert_eq!(
1543 result_obj.get("new_field").unwrap().as_string().unwrap(),
1544 "new_value"
1545 );
1546 assert_eq!(
1547 result_obj.get("another_field").unwrap().as_int32().unwrap(),
1548 99
1549 );
1550 }
1551
1552 #[test]
1553 fn test_complex_nested_filtering_injection() {
1554 let mut builder = VariantBuilder::new().with_field_names([
1557 "active_count",
1558 "active_users",
1559 "computed_score",
1560 "processed_at",
1561 "status",
1562 ]);
1563
1564 {
1565 let mut root_obj = builder.new_object();
1566 root_obj.insert("metadata", "original");
1567
1568 {
1569 let mut users_list = root_obj.new_list("users");
1570
1571 {
1573 let mut user1 = users_list.new_object();
1574 user1.insert("id", 1i32);
1575 user1.insert("name", "Alice");
1576 user1.insert("active", true);
1577 user1.finish();
1578 }
1579
1580 {
1582 let mut user2 = users_list.new_object();
1583 user2.insert("id", 2i32);
1584 user2.insert("name", "Bob");
1585 user2.insert("active", false);
1586 user2.finish();
1587 }
1588
1589 {
1591 let mut user3 = users_list.new_object();
1592 user3.insert("id", 3i32);
1593 user3.insert("name", "Charlie");
1594 user3.insert("active", true);
1595 user3.finish();
1596 }
1597
1598 users_list.finish();
1599 }
1600
1601 root_obj.insert("total_count", 3i32);
1602 root_obj.finish();
1603 }
1604 let (metadata1, value1) = builder.finish();
1605 let original_variant = Variant::try_new(&metadata1, &value1).unwrap();
1606 let original_obj = original_variant.as_object().unwrap();
1607 let original_users = original_obj.get("users").unwrap();
1608 let original_users = original_users.as_list().unwrap();
1609
1610 let metadata2 = VariantMetadata::new(&metadata1);
1612 let mut metadata2 = ReadOnlyMetadataBuilder::new(&metadata2);
1613 let mut builder2 = ValueBuilder::new();
1614 let state = ParentState::variant(&mut builder2, &mut metadata2);
1615 {
1616 let mut root_obj = ObjectBuilder::new(state, true);
1617
1618 root_obj.insert_bytes("metadata", original_obj.get("metadata").unwrap());
1620
1621 root_obj.insert("processed_at", "2024-01-01T00:00:00Z");
1623
1624 {
1625 let mut filtered_users = root_obj.new_list("active_users");
1626
1627 for i in 0..original_users.len() {
1629 let user = original_users.get(i).unwrap();
1630 let user = user.as_object().unwrap();
1631 if user.get("active").unwrap().as_boolean().unwrap() {
1632 {
1633 let mut new_user = filtered_users.new_object();
1634
1635 new_user.insert_bytes("id", user.get("id").unwrap());
1637 new_user.insert_bytes("name", user.get("name").unwrap());
1638
1639 let user_id = user.get("id").unwrap().as_int32().unwrap();
1641 new_user.insert("computed_score", user_id * 10);
1642
1643 new_user.insert("status", "verified");
1645
1646 new_user.finish();
1647 }
1648 }
1649 }
1650
1651 {
1653 let mut new_user = filtered_users.new_object();
1654 new_user.insert("id", 999i32);
1655 new_user.insert("name", "System User");
1656 new_user.insert("computed_score", 0i32);
1657 new_user.insert("status", "system");
1658 new_user.finish();
1659 }
1660
1661 filtered_users.finish();
1662 }
1663
1664 root_obj.insert("active_count", 3i32); root_obj.finish();
1668 }
1669 let value2 = builder2.into_inner();
1670 let result_variant = Variant::try_new(&metadata1, &value2).unwrap();
1671 let result_obj = result_variant.as_object().unwrap();
1672
1673 assert_eq!(
1675 result_obj.get("metadata").unwrap().as_string().unwrap(),
1676 "original"
1677 );
1678 assert_eq!(
1679 result_obj.get("processed_at").unwrap().as_string().unwrap(),
1680 "2024-01-01T00:00:00Z"
1681 );
1682 assert_eq!(
1683 result_obj.get("active_count").unwrap().as_int32().unwrap(),
1684 3
1685 );
1686
1687 let active_users = result_obj.get("active_users").unwrap();
1688 let active_users = active_users.as_list().unwrap();
1689 assert_eq!(active_users.len(), 3);
1690
1691 let alice = active_users.get(0).unwrap();
1693 let alice = alice.as_object().unwrap();
1694 assert_eq!(alice.get("id").unwrap().as_int32().unwrap(), 1);
1695 assert_eq!(alice.get("name").unwrap().as_string().unwrap(), "Alice");
1696 assert_eq!(alice.get("computed_score").unwrap().as_int32().unwrap(), 10);
1697 assert_eq!(
1698 alice.get("status").unwrap().as_string().unwrap(),
1699 "verified"
1700 );
1701 assert!(alice.get("active").is_none()); let charlie = active_users.get(1).unwrap();
1705 let charlie = charlie.as_object().unwrap();
1706 assert_eq!(charlie.get("id").unwrap().as_int32().unwrap(), 3);
1707 assert_eq!(charlie.get("name").unwrap().as_string().unwrap(), "Charlie");
1708 assert_eq!(
1709 charlie.get("computed_score").unwrap().as_int32().unwrap(),
1710 30
1711 );
1712 assert_eq!(
1713 charlie.get("status").unwrap().as_string().unwrap(),
1714 "verified"
1715 );
1716
1717 let system_user = active_users.get(2).unwrap();
1719 let system_user = system_user.as_object().unwrap();
1720 assert_eq!(system_user.get("id").unwrap().as_int32().unwrap(), 999);
1721 assert_eq!(
1722 system_user.get("name").unwrap().as_string().unwrap(),
1723 "System User"
1724 );
1725 assert_eq!(
1726 system_user
1727 .get("computed_score")
1728 .unwrap()
1729 .as_int32()
1730 .unwrap(),
1731 0
1732 );
1733 assert_eq!(
1734 system_user.get("status").unwrap().as_string().unwrap(),
1735 "system"
1736 );
1737 }
1738}