1use bytes::{BufMut, BytesMut};
105use serde::ser::{self, Serialize};
106use std::fmt;
107
108#[derive(Debug, thiserror::Error)]
111#[non_exhaustive]
112pub enum RowBinaryError {
113 #[error("type has no RowBinary representation: {0}")]
115 Unsupported(&'static str),
116 #[error("sequences must have a known length ahead of time")]
118 SequenceMustHaveLength,
119 #[error(
122 "#[serde(flatten)] is not supported by RowBinary: it produces \
123 length-less, unordered fields; inline the flattened fields into the \
124 row struct in column order instead"
125 )]
126 FlattenUnsupported,
127 #[error(
130 "nested Option (Option<Option<T>>) has no ClickHouse type: \
131 ClickHouse forbids Nullable(Nullable(T))"
132 )]
133 NestedOption,
134 #[error(
141 "struct declared {expected} field(s) but serialized {got}: RowBinary rows are positional and must be fixed-width"
142 )]
143 FieldCountMismatch {
144 expected: usize,
146 got: usize,
148 },
149 #[error("variant discriminant {0} exceeds 255")]
151 VariantOutOfRange(u32),
152 #[error("serialize error: {0}")]
154 Custom(String),
155}
156
157impl ser::Error for RowBinaryError {
158 fn custom<T: fmt::Display>(msg: T) -> Self {
159 RowBinaryError::Custom(msg.to_string())
160 }
161}
162
163pub fn serialize_row<T: Serialize + ?Sized>(
168 row: &T,
169 buf: &mut BytesMut,
170) -> Result<(), RowBinaryError> {
171 row.serialize(&mut RowBinarySer {
172 buf,
173 option_inner: false,
174 struct_depth: 0,
175 top_expected: 0,
176 top_written: 0,
177 })
178}
179
180pub use crate::types::{DateTime64Millis, DateTimeSeconds};
181
182fn put_leb128(buf: &mut BytesMut, mut value: u64) {
183 loop {
184 let byte = (value & 0x7f) as u8;
185 value >>= 7;
186 if value == 0 {
187 buf.put_u8(byte);
188 break;
189 }
190 buf.put_u8(byte | 0x80);
191 }
192}
193
194struct RowBinarySer<'a> {
195 buf: &'a mut BytesMut,
196 option_inner: bool,
202 struct_depth: u32,
205 top_expected: usize,
207 top_written: usize,
209}
210
211impl<'a, 'b> ser::Serializer for &'a mut RowBinarySer<'b> {
212 type Ok = ();
213 type Error = RowBinaryError;
214 type SerializeSeq = Self;
215 type SerializeTuple = Self;
216 type SerializeTupleStruct = Self;
217 type SerializeTupleVariant = ser::Impossible<(), RowBinaryError>;
218 type SerializeMap = Self;
219 type SerializeStruct = Self;
220 type SerializeStructVariant = ser::Impossible<(), RowBinaryError>;
221
222 #[inline]
223 fn serialize_bool(self, v: bool) -> Result<(), RowBinaryError> {
224 self.buf.put_u8(u8::from(v));
225 Ok(())
226 }
227
228 #[inline]
229 fn serialize_i8(self, v: i8) -> Result<(), RowBinaryError> {
230 self.buf.put_i8(v);
231 Ok(())
232 }
233
234 #[inline]
235 fn serialize_i16(self, v: i16) -> Result<(), RowBinaryError> {
236 self.buf.put_i16_le(v);
237 Ok(())
238 }
239
240 #[inline]
241 fn serialize_i32(self, v: i32) -> Result<(), RowBinaryError> {
242 self.buf.put_i32_le(v);
243 Ok(())
244 }
245
246 #[inline]
247 fn serialize_i64(self, v: i64) -> Result<(), RowBinaryError> {
248 self.buf.put_i64_le(v);
249 Ok(())
250 }
251
252 #[inline]
253 fn serialize_i128(self, v: i128) -> Result<(), RowBinaryError> {
254 self.buf.put_i128_le(v);
255 Ok(())
256 }
257
258 #[inline]
259 fn serialize_u8(self, v: u8) -> Result<(), RowBinaryError> {
260 self.buf.put_u8(v);
261 Ok(())
262 }
263
264 #[inline]
265 fn serialize_u16(self, v: u16) -> Result<(), RowBinaryError> {
266 self.buf.put_u16_le(v);
267 Ok(())
268 }
269
270 #[inline]
271 fn serialize_u32(self, v: u32) -> Result<(), RowBinaryError> {
272 self.buf.put_u32_le(v);
273 Ok(())
274 }
275
276 #[inline]
277 fn serialize_u64(self, v: u64) -> Result<(), RowBinaryError> {
278 self.buf.put_u64_le(v);
279 Ok(())
280 }
281
282 #[inline]
283 fn serialize_u128(self, v: u128) -> Result<(), RowBinaryError> {
284 self.buf.put_u128_le(v);
285 Ok(())
286 }
287
288 #[inline]
289 fn serialize_f32(self, v: f32) -> Result<(), RowBinaryError> {
290 self.buf.put_f32_le(v);
291 Ok(())
292 }
293
294 #[inline]
295 fn serialize_f64(self, v: f64) -> Result<(), RowBinaryError> {
296 self.buf.put_f64_le(v);
297 Ok(())
298 }
299
300 fn serialize_char(self, _v: char) -> Result<(), RowBinaryError> {
301 Err(RowBinaryError::Unsupported(
302 "char (use a String column instead)",
303 ))
304 }
305
306 #[inline]
307 fn serialize_str(self, v: &str) -> Result<(), RowBinaryError> {
308 put_leb128(self.buf, v.len() as u64);
309 self.buf.put_slice(v.as_bytes());
310 Ok(())
311 }
312
313 #[inline]
314 fn serialize_bytes(self, v: &[u8]) -> Result<(), RowBinaryError> {
315 put_leb128(self.buf, v.len() as u64);
316 self.buf.put_slice(v);
317 Ok(())
318 }
319
320 #[inline]
321 fn serialize_none(self) -> Result<(), RowBinaryError> {
322 if self.option_inner {
323 return Err(RowBinaryError::NestedOption);
325 }
326 self.buf.put_u8(1);
328 Ok(())
329 }
330
331 #[inline]
332 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<(), RowBinaryError> {
333 if self.option_inner {
334 return Err(RowBinaryError::NestedOption);
336 }
337 self.buf.put_u8(0);
340 self.option_inner = true;
341 let result = value.serialize(&mut *self);
342 self.option_inner = false;
343 result
344 }
345
346 fn serialize_unit(self) -> Result<(), RowBinaryError> {
347 Err(RowBinaryError::Unsupported("() has no column type"))
348 }
349
350 fn serialize_unit_struct(self, name: &'static str) -> Result<(), RowBinaryError> {
351 let _ = name;
352 Err(RowBinaryError::Unsupported("unit struct"))
353 }
354
355 fn serialize_unit_variant(
356 self,
357 _name: &'static str,
358 _variant_index: u32,
359 _variant: &'static str,
360 ) -> Result<(), RowBinaryError> {
361 Err(RowBinaryError::Unsupported(
362 "unit enum variant (map enums to an integer or String column explicitly)",
363 ))
364 }
365
366 #[inline]
367 fn serialize_newtype_struct<T: Serialize + ?Sized>(
368 self,
369 _name: &'static str,
370 value: &T,
371 ) -> Result<(), RowBinaryError> {
372 value.serialize(self)
373 }
374
375 fn serialize_newtype_variant<T: Serialize + ?Sized>(
376 self,
377 _name: &'static str,
378 variant_index: u32,
379 _variant: &'static str,
380 value: &T,
381 ) -> Result<(), RowBinaryError> {
382 self.option_inner = false;
383 let idx = u8::try_from(variant_index)
392 .map_err(|_| RowBinaryError::VariantOutOfRange(variant_index))?;
393 self.buf.put_u8(idx);
394 value.serialize(self)
395 }
396
397 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, RowBinaryError> {
398 self.option_inner = false;
399 let len = len.ok_or(RowBinaryError::SequenceMustHaveLength)?;
400 put_leb128(self.buf, len as u64);
401 Ok(self)
402 }
403
404 #[inline]
405 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, RowBinaryError> {
406 self.option_inner = false;
407 Ok(self)
408 }
409
410 #[inline]
411 fn serialize_tuple_struct(
412 self,
413 _name: &'static str,
414 _len: usize,
415 ) -> Result<Self::SerializeTupleStruct, RowBinaryError> {
416 self.option_inner = false;
417 Ok(self)
418 }
419
420 fn serialize_tuple_variant(
421 self,
422 _name: &'static str,
423 _variant_index: u32,
424 _variant: &'static str,
425 _len: usize,
426 ) -> Result<Self::SerializeTupleVariant, RowBinaryError> {
427 Err(RowBinaryError::Unsupported("tuple enum variant"))
428 }
429
430 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, RowBinaryError> {
431 self.option_inner = false;
432 let len = len.ok_or(RowBinaryError::FlattenUnsupported)?;
437 put_leb128(self.buf, len as u64);
438 Ok(self)
439 }
440
441 #[inline]
442 fn serialize_struct(
443 self,
444 _name: &'static str,
445 len: usize,
446 ) -> Result<Self::SerializeStruct, RowBinaryError> {
447 self.option_inner = false;
448 if self.struct_depth == 0 {
452 self.top_expected = len;
453 self.top_written = 0;
454 }
455 self.struct_depth += 1;
456 Ok(self)
457 }
458
459 fn serialize_struct_variant(
460 self,
461 _name: &'static str,
462 _variant_index: u32,
463 _variant: &'static str,
464 _len: usize,
465 ) -> Result<Self::SerializeStructVariant, RowBinaryError> {
466 Err(RowBinaryError::Unsupported("struct enum variant"))
467 }
468
469 #[inline]
470 fn is_human_readable(&self) -> bool {
471 false
472 }
473}
474
475impl<'a, 'b> ser::SerializeSeq for &'a mut RowBinarySer<'b> {
476 type Ok = ();
477 type Error = RowBinaryError;
478
479 #[inline]
480 fn serialize_element<T: Serialize + ?Sized>(
481 &mut self,
482 value: &T,
483 ) -> Result<(), RowBinaryError> {
484 value.serialize(&mut **self)
485 }
486
487 #[inline]
488 fn end(self) -> Result<(), RowBinaryError> {
489 Ok(())
490 }
491}
492
493impl<'a, 'b> ser::SerializeTuple for &'a mut RowBinarySer<'b> {
494 type Ok = ();
495 type Error = RowBinaryError;
496
497 #[inline]
498 fn serialize_element<T: Serialize + ?Sized>(
499 &mut self,
500 value: &T,
501 ) -> Result<(), RowBinaryError> {
502 value.serialize(&mut **self)
503 }
504
505 #[inline]
506 fn end(self) -> Result<(), RowBinaryError> {
507 Ok(())
508 }
509}
510
511impl<'a, 'b> ser::SerializeTupleStruct for &'a mut RowBinarySer<'b> {
512 type Ok = ();
513 type Error = RowBinaryError;
514
515 #[inline]
516 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), RowBinaryError> {
517 value.serialize(&mut **self)
518 }
519
520 #[inline]
521 fn end(self) -> Result<(), RowBinaryError> {
522 Ok(())
523 }
524}
525
526impl<'a, 'b> ser::SerializeMap for &'a mut RowBinarySer<'b> {
527 type Ok = ();
528 type Error = RowBinaryError;
529
530 #[inline]
531 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), RowBinaryError> {
532 key.serialize(&mut **self)
533 }
534
535 #[inline]
536 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), RowBinaryError> {
537 value.serialize(&mut **self)
538 }
539
540 #[inline]
541 fn end(self) -> Result<(), RowBinaryError> {
542 Ok(())
543 }
544}
545
546impl<'a, 'b> ser::SerializeStruct for &'a mut RowBinarySer<'b> {
547 type Ok = ();
548 type Error = RowBinaryError;
549
550 #[inline]
551 fn serialize_field<T: Serialize + ?Sized>(
552 &mut self,
553 _key: &'static str,
554 value: &T,
555 ) -> Result<(), RowBinaryError> {
556 if self.struct_depth == 1 {
559 self.top_written += 1;
560 }
561 value.serialize(&mut **self)
562 }
563
564 #[inline]
565 fn end(self) -> Result<(), RowBinaryError> {
566 self.struct_depth -= 1;
567 if self.struct_depth == 0 && self.top_written != self.top_expected {
568 return Err(RowBinaryError::FieldCountMismatch {
569 expected: self.top_expected,
570 got: self.top_written,
571 });
572 }
573 Ok(())
574 }
575}
576
577#[cfg(test)]
578mod tests {
579 use super::*;
580 use serde::Serialize;
581
582 fn enc<T: Serialize>(v: &T) -> Vec<u8> {
583 let mut buf = BytesMut::new();
584 serialize_row(v, &mut buf).expect("serialize");
585 buf.to_vec()
586 }
587
588 #[test]
589 fn integers_are_little_endian_fixed_width() {
590 assert_eq!(enc(&0x0102_0304u32), [0x04, 0x03, 0x02, 0x01]);
591 assert_eq!(enc(&-2i16), [0xfe, 0xff]);
592 assert_eq!(enc(&1u8), [0x01]);
593 assert_eq!(
594 enc(&0x0102_0304_0506_0708u64),
595 [0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]
596 );
597 assert_eq!(enc(&1u128).len(), 16);
598 }
599
600 #[test]
601 fn floats_and_bools() {
602 assert_eq!(enc(&1.0f32), 1.0f32.to_le_bytes());
603 assert_eq!(enc(&-2.5f64), (-2.5f64).to_le_bytes());
604 assert_eq!(enc(&true), [1]);
605 assert_eq!(enc(&false), [0]);
606 }
607
608 #[test]
609 fn strings_are_leb128_prefixed() {
610 assert_eq!(enc(&"abc"), [3, b'a', b'b', b'c']);
611 assert_eq!(enc(&""), [0]);
612 let long = "x".repeat(300);
614 let bytes = enc(&long);
615 assert_eq!(&bytes[..2], &[0xac, 0x02]);
616 assert_eq!(bytes.len(), 302);
617 }
618
619 #[test]
620 fn options_use_null_prefix_bytes() {
621 assert_eq!(enc(&Option::<u8>::None), [1]);
623 assert_eq!(enc(&Some(7u8)), [0, 7]);
624 assert_eq!(enc(&Some("hi")), [0, 2, b'h', b'i']);
625 }
626
627 #[test]
628 fn sequences_carry_a_count_tuples_do_not() {
629 assert_eq!(enc(&vec![1u8, 2, 3]), [3, 1, 2, 3]);
630 assert_eq!(enc(&Vec::<u8>::new()), [0]);
631 assert_eq!(enc(&(1u8, 2u8, 3u8)), [1, 2, 3]);
632 assert_eq!(
633 enc(&[1u8, 2, 3]),
634 [1, 2, 3],
635 "fixed arrays = FixedString/Tuple"
636 );
637 }
638
639 #[test]
640 fn maps_are_counted_key_value_pairs() {
641 let mut m = std::collections::BTreeMap::new();
642 m.insert("a".to_string(), 1u8);
643 m.insert("b".to_string(), 2u8);
644 assert_eq!(enc(&m), [2, 1, b'a', 1, 1, b'b', 2]);
645 }
646
647 #[test]
648 fn structs_encode_fields_in_declaration_order() {
649 #[derive(Serialize)]
650 struct Row {
651 id: u64,
652 name: String,
653 score: Option<f64>,
654 }
655 let bytes = enc(&Row {
656 id: 5,
657 name: "n".into(),
658 score: None,
659 });
660 assert_eq!(bytes, [5, 0, 0, 0, 0, 0, 0, 0, 1, b'n', 1]);
661 }
662
663 #[test]
664 fn spike_fixture_row_matches_hand_encoding() {
665 #[derive(Serialize)]
668 struct SpikeRow {
669 id: u64,
670 name: String,
671 }
672 let bytes = enc(&SpikeRow {
673 id: 1500,
674 name: "raw-1500".into(),
675 });
676 let mut expected = 1500u64.to_le_bytes().to_vec();
677 expected.push(8);
678 expected.extend_from_slice(b"raw-1500");
679 assert_eq!(bytes, expected);
680 }
681
682 #[test]
683 fn newtypes_are_transparent() {
684 assert_eq!(enc(&DateTime64Millis(1_000)), enc(&1_000i64));
685 assert_eq!(enc(&DateTimeSeconds(42)), enc(&42u32));
686 }
687
688 #[test]
689 fn unsupported_types_error_instead_of_panicking() {
690 #[derive(Serialize)]
691 enum Unit {
692 A,
693 }
694 assert!(matches!(
695 serialize_row(&Unit::A, &mut BytesMut::new()),
696 Err(RowBinaryError::Unsupported(_))
697 ));
698 assert!(matches!(
699 serialize_row(&'x', &mut BytesMut::new()),
700 Err(RowBinaryError::Unsupported(_))
701 ));
702 assert!(matches!(
703 serialize_row(&(), &mut BytesMut::new()),
704 Err(RowBinaryError::Unsupported(_))
705 ));
706 }
707
708 #[test]
709 fn variant_newtype_gets_a_discriminant_byte() {
710 #[derive(Serialize)]
711 enum V {
712 #[allow(dead_code)]
713 A(u8),
714 B(u16),
715 }
716 assert_eq!(enc(&V::B(7)), [1, 7, 0]);
720 }
721
722 #[test]
723 fn nested_option_is_rejected() {
724 assert!(matches!(
727 serialize_row(&Some(Option::<u8>::None), &mut BytesMut::new()),
728 Err(RowBinaryError::NestedOption)
729 ));
730 assert!(matches!(
731 serialize_row(&Some(Some(7u8)), &mut BytesMut::new()),
732 Err(RowBinaryError::NestedOption)
733 ));
734
735 assert_eq!(enc(&Some(7u8)), [0, 7]);
738 assert_eq!(enc(&None::<u8>), [1]);
739 #[derive(Serialize)]
740 struct Row {
741 a: Option<u8>,
742 b: Option<u8>,
743 }
744 assert_eq!(
745 enc(&Row {
746 a: Some(1),
747 b: None
748 }),
749 [0, 1, 1]
750 );
751 assert_eq!(enc(&vec![Some(1u8), None]), [2, 0, 1, 1]);
752 }
753
754 #[test]
755 fn flatten_is_rejected_with_a_clear_error() {
756 #[derive(Serialize)]
757 struct Inner {
758 x: u8,
759 }
760 #[derive(Serialize)]
761 struct Flat {
762 id: u8,
763 #[serde(flatten)]
764 inner: Inner,
765 }
766 let err = serialize_row(
767 &Flat {
768 id: 1,
769 inner: Inner { x: 2 },
770 },
771 &mut BytesMut::new(),
772 )
773 .unwrap_err();
774 assert!(matches!(err, RowBinaryError::FlattenUnsupported), "{err}");
775 assert!(err.to_string().contains("flatten"), "{err}");
777 }
778
779 #[test]
780 fn struct_field_count_mismatch_is_caught() {
781 struct Liar;
784 impl Serialize for Liar {
785 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
786 use serde::ser::SerializeStruct;
787 let mut st = s.serialize_struct("Liar", 3)?;
788 st.serialize_field("a", &1u8)?;
789 st.end()
790 }
791 }
792 assert!(
793 matches!(
794 serialize_row(&Liar, &mut BytesMut::new()),
795 Err(RowBinaryError::FieldCountMismatch {
796 expected: 3,
797 got: 1
798 })
799 ),
800 "declared/serialized field-count mismatch must error"
801 );
802 }
803
804 #[test]
805 fn serde_repr_enums_encode_as_enum8_and_enum16() {
806 #[derive(serde_repr::Serialize_repr)]
810 #[repr(i8)]
811 enum Level8 {
812 #[allow(dead_code)]
813 Low = -1,
814 High = 2,
815 }
816 #[derive(serde_repr::Serialize_repr)]
817 #[repr(i16)]
818 enum Level16 {
819 Big = 300,
820 }
821 assert_eq!(enc(&Level8::High), [2]);
822 assert_eq!(enc(&Level8::Low), [0xff]);
823 assert_eq!(enc(&Level16::Big), 300i16.to_le_bytes());
824 }
825
826 #[test]
827 fn ipv6_default_impl_matches_the_16_byte_wire_format() {
828 use std::net::Ipv6Addr;
832 let localhost = Ipv6Addr::LOCALHOST;
833 assert_eq!(enc(&localhost), localhost.octets());
834 let addr: Ipv6Addr = "2001:db8::8a2e:370:7334".parse().unwrap();
835 assert_eq!(enc(&addr), addr.octets());
836 }
837
838 #[test]
839 fn skip_serializing_if_yields_a_short_row_the_serializer_cannot_detect() {
840 #[derive(Serialize)]
844 struct Row {
845 id: u8,
846 #[serde(skip_serializing_if = "Option::is_none")]
847 score: Option<u8>,
848 name: String,
849 }
850 assert_eq!(
852 enc(&Row {
853 id: 1,
854 score: Some(9),
855 name: "ab".into()
856 }),
857 [1, 0, 9, 2, b'a', b'b']
858 );
859 assert_eq!(
862 enc(&Row {
863 id: 1,
864 score: None,
865 name: "ab".into()
866 }),
867 [1, 2, b'a', b'b']
868 );
869 }
870}