1use crate::time_duration::TimeDuration;
2use crate::timestamp::Timestamp;
3use crate::{i256, u256, AlgebraicType, AlgebraicValue, ProductValue, Serialize, SumValue, ValueWithType};
4use crate::{ser, ProductType, ProductTypeElement};
5use core::fmt;
6use core::fmt::Write as _;
7use derive_more::{Display, From, Into};
8use std::borrow::Cow;
9use std::marker::PhantomData;
10
11pub trait Satn: ser::Serialize {
13 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 Writer::with(f, |f| self.serialize(SatnFormatter { f }))?;
16 Ok(())
17 }
18
19 fn fmt_psql(&self, f: &mut fmt::Formatter, ty: &PsqlType<'_>) -> fmt::Result {
21 Writer::with(f, |f| {
22 self.serialize(TypedSerializer {
23 ty,
24 f: &mut SqlFormatter {
25 fmt: SatnFormatter { f },
26 ty,
27 },
28 })
29 })?;
30 Ok(())
31 }
32
33 fn to_satn(&self) -> String {
35 Wrapper::from_ref(self).to_string()
36 }
37
38 fn to_satn_pretty(&self) -> String {
40 format!("{:#}", Wrapper::from_ref(self))
41 }
42}
43
44impl<T: ser::Serialize + ?Sized> Satn for T {}
45
46#[repr(transparent)]
50pub struct Wrapper<T: ?Sized>(pub T);
51
52impl<T: ?Sized> Wrapper<T> {
53 pub fn from_ref(t: &T) -> &Self {
55 unsafe { &*(t as *const T as *const Self) }
58 }
59}
60
61impl<T: Satn + ?Sized> fmt::Display for Wrapper<T> {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 self.0.fmt(f)
64 }
65}
66
67impl<T: Satn + ?Sized> fmt::Debug for Wrapper<T> {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 self.0.fmt(f)
70 }
71}
72
73pub struct PsqlWrapper<'a, T: ?Sized> {
77 pub ty: PsqlType<'a>,
78 pub value: T,
79}
80
81impl<T: ?Sized> PsqlWrapper<'_, T> {
82 pub fn from_ref(t: &T) -> &Self {
84 unsafe { &*(t as *const T as *const Self) }
87 }
88}
89
90impl<T: Satn + ?Sized> fmt::Display for PsqlWrapper<'_, T> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 self.value.fmt_psql(f, &self.ty)
93 }
94}
95
96impl<T: Satn + ?Sized> fmt::Debug for PsqlWrapper<'_, T> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 self.value.fmt_psql(f, &self.ty)
99 }
100}
101
102struct EntryWrapper<'a, 'f, const SEP: char> {
104 fmt: Writer<'a, 'f>,
106 has_fields: bool,
109}
110
111impl<'a, 'f, const SEP: char> EntryWrapper<'a, 'f, SEP> {
112 fn new(fmt: Writer<'a, 'f>) -> Self {
114 Self { fmt, has_fields: false }
115 }
116
117 fn entry(&mut self, entry: impl FnOnce(Writer) -> fmt::Result) -> fmt::Result {
121 let res = (|| match &mut self.fmt {
122 Writer::Pretty(f) => {
123 if !self.has_fields {
124 f.write_char('\n')?;
125 }
126 f.state.indent += 1;
127 entry(Writer::Pretty(f.as_mut()))?;
128 f.write_char(SEP)?;
129 f.write_char('\n')?;
130 f.state.indent -= 1;
131 Ok(())
132 }
133 Writer::Normal(f) => {
134 if self.has_fields {
135 f.write_char(SEP)?;
136 f.write_char(' ')?;
137 }
138 entry(Writer::Normal(f))
139 }
140 })();
141 self.has_fields = true;
142 res
143 }
144}
145
146enum Writer<'a, 'f> {
148 Normal(&'a mut fmt::Formatter<'f>),
150 Pretty(IndentedWriter<'a, 'f>),
152}
153
154impl<'f> Writer<'_, 'f> {
155 fn with<R>(f: &mut fmt::Formatter<'_>, func: impl FnOnce(Writer<'_, '_>) -> R) -> R {
157 let mut state;
158 let f = if f.alternate() {
160 state = IndentState {
161 indent: 0,
162 on_newline: true,
163 };
164 Writer::Pretty(IndentedWriter { f, state: &mut state })
165 } else {
166 Writer::Normal(f)
167 };
168 func(f)
169 }
170
171 fn as_mut(&mut self) -> Writer<'_, 'f> {
173 match self {
174 Writer::Normal(f) => Writer::Normal(f),
175 Writer::Pretty(f) => Writer::Pretty(f.as_mut()),
176 }
177 }
178}
179
180struct IndentedWriter<'a, 'f> {
182 f: &'a mut fmt::Formatter<'f>,
183 state: &'a mut IndentState,
184}
185
186struct IndentState {
188 indent: u32,
190 on_newline: bool,
192}
193
194impl<'f> IndentedWriter<'_, 'f> {
195 fn as_mut(&mut self) -> IndentedWriter<'_, 'f> {
197 IndentedWriter {
198 f: self.f,
199 state: self.state,
200 }
201 }
202}
203
204impl fmt::Write for IndentedWriter<'_, '_> {
205 fn write_str(&mut self, s: &str) -> fmt::Result {
206 for s in s.split_inclusive('\n') {
207 if self.state.on_newline {
208 for _ in 0..self.state.indent {
210 self.f.write_str(" ")?;
211 }
212 }
213
214 self.state.on_newline = s.ends_with('\n');
215 self.f.write_str(s)?;
216 }
217 Ok(())
218 }
219}
220
221impl fmt::Write for Writer<'_, '_> {
222 fn write_str(&mut self, s: &str) -> fmt::Result {
223 match self {
224 Writer::Normal(f) => f.write_str(s),
225 Writer::Pretty(f) => f.write_str(s),
226 }
227 }
228}
229
230struct SatnFormatter<'a, 'f> {
232 f: Writer<'a, 'f>,
234}
235
236impl SatnFormatter<'_, '_> {
237 fn ser_variant<T: ser::Serialize + ?Sized>(
238 &mut self,
239 _tag: u8,
240 name: Option<&str>,
241 value: &T,
242 ) -> Result<(), SatnError> {
243 write!(self, "(")?;
244 EntryWrapper::<','>::new(self.f.as_mut()).entry(|mut f| {
245 if let Some(name) = name {
246 write!(f, "{name}")?;
247 }
248 write!(f, " = ")?;
249 value.serialize(SatnFormatter { f })?;
250 Ok(())
251 })?;
252 write!(self, ")")?;
253
254 Ok(())
255 }
256}
257#[derive(From, Into)]
259pub struct SatnError(fmt::Error);
260
261impl ser::Error for SatnError {
262 fn custom<T: fmt::Display>(_msg: T) -> Self {
263 Self(fmt::Error)
264 }
265}
266
267impl SatnFormatter<'_, '_> {
268 #[inline(always)]
270 fn write_fmt(&mut self, args: fmt::Arguments) -> Result<(), SatnError> {
271 self.f.write_fmt(args)?;
272 Ok(())
273 }
274}
275
276impl<'a, 'f> ser::Serializer for SatnFormatter<'a, 'f> {
277 type Ok = ();
278 type Error = SatnError;
279 type SerializeArray = ArrayFormatter<'a, 'f>;
280 type SerializeSeqProduct = SeqFormatter<'a, 'f>;
281 type SerializeNamedProduct = NamedFormatter<'a, 'f>;
282
283 fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
284 write!(self, "{v}")
285 }
286 fn serialize_u8(mut self, v: u8) -> Result<Self::Ok, Self::Error> {
287 write!(self, "{v}")
288 }
289 fn serialize_u16(mut self, v: u16) -> Result<Self::Ok, Self::Error> {
290 write!(self, "{v}")
291 }
292 fn serialize_u32(mut self, v: u32) -> Result<Self::Ok, Self::Error> {
293 write!(self, "{v}")
294 }
295 fn serialize_u64(mut self, v: u64) -> Result<Self::Ok, Self::Error> {
296 write!(self, "{v}")
297 }
298 fn serialize_u128(mut self, v: u128) -> Result<Self::Ok, Self::Error> {
299 write!(self, "{v}")
300 }
301 fn serialize_u256(mut self, v: u256) -> Result<Self::Ok, Self::Error> {
302 write!(self, "{v}")
303 }
304 fn serialize_i8(mut self, v: i8) -> Result<Self::Ok, Self::Error> {
305 write!(self, "{v}")
306 }
307 fn serialize_i16(mut self, v: i16) -> Result<Self::Ok, Self::Error> {
308 write!(self, "{v}")
309 }
310 fn serialize_i32(mut self, v: i32) -> Result<Self::Ok, Self::Error> {
311 write!(self, "{v}")
312 }
313 fn serialize_i64(mut self, v: i64) -> Result<Self::Ok, Self::Error> {
314 write!(self, "{v}")
315 }
316 fn serialize_i128(mut self, v: i128) -> Result<Self::Ok, Self::Error> {
317 write!(self, "{v}")
318 }
319 fn serialize_i256(mut self, v: i256) -> Result<Self::Ok, Self::Error> {
320 write!(self, "{v}")
321 }
322 fn serialize_f32(mut self, v: f32) -> Result<Self::Ok, Self::Error> {
323 write!(self, "{v}")
324 }
325 fn serialize_f64(mut self, v: f64) -> Result<Self::Ok, Self::Error> {
326 write!(self, "{v}")
327 }
328
329 fn serialize_str(mut self, v: &str) -> Result<Self::Ok, Self::Error> {
330 write!(self, "\"{v}\"")
331 }
332
333 fn serialize_bytes(mut self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
334 write!(self, "0x{}", hex::encode(v))
335 }
336
337 fn serialize_array(mut self, _len: usize) -> Result<Self::SerializeArray, Self::Error> {
338 write!(self, "[")?; Ok(ArrayFormatter {
340 f: EntryWrapper::new(self.f),
341 })
342 }
343
344 fn serialize_seq_product(self, len: usize) -> Result<Self::SerializeSeqProduct, Self::Error> {
345 self.serialize_named_product(len).map(|inner| SeqFormatter { inner })
347 }
348
349 fn serialize_named_product(mut self, _len: usize) -> Result<Self::SerializeNamedProduct, Self::Error> {
350 write!(self, "(")?; Ok(NamedFormatter {
352 f: EntryWrapper::new(self.f),
353 idx: 0,
354 })
355 }
356
357 fn serialize_variant<T: ser::Serialize + ?Sized>(
358 mut self,
359 tag: u8,
360 name: Option<&str>,
361 value: &T,
362 ) -> Result<Self::Ok, Self::Error> {
363 self.ser_variant(tag, name, value)
364 }
365}
366
367struct ArrayFormatter<'a, 'f> {
369 f: EntryWrapper<'a, 'f, ','>,
371}
372
373impl ser::SerializeArray for ArrayFormatter<'_, '_> {
374 type Ok = ();
375 type Error = SatnError;
376
377 fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
378 self.f.entry(|f| elem.serialize(SatnFormatter { f }).map_err(|e| e.0))?;
379 Ok(())
380 }
381
382 fn end(mut self) -> Result<Self::Ok, Self::Error> {
383 write!(self.f.fmt, "]")?;
384 Ok(())
385 }
386}
387
388struct SeqFormatter<'a, 'f> {
390 inner: NamedFormatter<'a, 'f>,
392}
393
394impl ser::SerializeSeqProduct for SeqFormatter<'_, '_> {
395 type Ok = ();
396 type Error = SatnError;
397
398 fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
399 ser::SerializeNamedProduct::serialize_element(&mut self.inner, None, elem)
400 }
401
402 fn end(self) -> Result<Self::Ok, Self::Error> {
403 ser::SerializeNamedProduct::end(self.inner)
404 }
405}
406
407struct NamedFormatter<'a, 'f> {
409 f: EntryWrapper<'a, 'f, ','>,
411 idx: usize,
413}
414
415impl ser::SerializeNamedProduct for NamedFormatter<'_, '_> {
416 type Ok = ();
417 type Error = SatnError;
418
419 fn serialize_element<T: ser::Serialize + ?Sized>(
420 &mut self,
421 name: Option<&str>,
422 elem: &T,
423 ) -> Result<(), Self::Error> {
424 let res = self.f.entry(|mut f| {
425 if let Some(name) = name {
427 write!(f, "{name}")?;
428 } else {
429 write!(f, "{}", self.idx)?;
430 }
431 write!(f, " = ")?;
432 elem.serialize(SatnFormatter { f })?;
433 Ok(())
434 });
435 self.idx += 1;
436 res?;
437 Ok(())
438 }
439
440 fn end(mut self) -> Result<Self::Ok, Self::Error> {
441 write!(self.f.fmt, ")")?;
442 Ok(())
443 }
444}
445
446#[derive(PartialEq, Copy, Clone, Debug)]
448pub enum PsqlClient {
449 SpacetimeDB,
450 Postgres,
451}
452
453pub struct PsqlChars {
454 pub start: char,
455 pub sep: &'static str,
456 pub end: char,
457 pub quote: &'static str,
458}
459
460impl PsqlClient {
461 pub fn format_chars(&self) -> PsqlChars {
462 match self {
463 PsqlClient::SpacetimeDB => PsqlChars {
464 start: '(',
465 sep: " =",
466 end: ')',
467 quote: "",
468 },
469 PsqlClient::Postgres => PsqlChars {
470 start: '{',
471 sep: ":",
472 end: '}',
473 quote: "\"",
474 },
475 }
476 }
477}
478
479#[derive(Debug, Copy, Clone, PartialEq, Display)]
481pub enum PsqlPrintFmt {
482 Hex,
484 Timestamp,
486 Duration,
488 Satn,
490}
491
492impl PsqlPrintFmt {
493 pub fn is_special(&self) -> bool {
494 self != &PsqlPrintFmt::Satn
495 }
496 pub fn use_fmt(tuple: &ProductType, field: &ProductTypeElement, name: Option<&str>) -> PsqlPrintFmt {
500 if tuple.is_identity()
501 || tuple.is_connection_id()
502 || field.algebraic_type.is_identity()
503 || field.algebraic_type.is_connection_id()
504 || name.map(ProductType::is_identity_tag).unwrap_or_default()
505 || name.map(ProductType::is_connection_id_tag).unwrap_or_default()
506 {
507 return PsqlPrintFmt::Hex;
508 };
509
510 if tuple.is_timestamp()
511 || field.algebraic_type.is_timestamp()
512 || name.map(ProductType::is_timestamp_tag).unwrap_or_default()
513 {
514 return PsqlPrintFmt::Timestamp;
515 };
516
517 if tuple.is_time_duration()
518 || field.algebraic_type.is_time_duration()
519 || name.map(ProductType::is_time_duration_tag).unwrap_or_default()
520 {
521 return PsqlPrintFmt::Duration;
522 };
523
524 PsqlPrintFmt::Satn
525 }
526}
527
528#[derive(Debug, Clone)]
530pub struct PsqlType<'a> {
531 pub client: PsqlClient,
533 pub tuple: &'a ProductType,
535 pub field: &'a ProductTypeElement,
537 pub idx: usize,
539}
540
541impl PsqlType<'_> {
542 pub fn use_fmt(&self) -> PsqlPrintFmt {
546 PsqlPrintFmt::use_fmt(self.tuple, self.field, None)
547 }
548}
549
550pub struct SqlFormatter<'a, 'f> {
552 fmt: SatnFormatter<'a, 'f>,
553 ty: &'a PsqlType<'a>,
554}
555
556pub trait TypedWriter {
561 type Error: ser::Error;
562
563 fn write<W: fmt::Display>(&mut self, value: W) -> Result<(), Self::Error>;
565
566 fn write_bool(&mut self, value: bool) -> Result<(), Self::Error>;
569 fn write_string(&mut self, value: &str) -> Result<(), Self::Error>;
570 fn write_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
571 fn write_hex(&mut self, value: &[u8]) -> Result<(), Self::Error>;
572 fn write_timestamp(&mut self, value: Timestamp) -> Result<(), Self::Error>;
573 fn write_duration(&mut self, value: TimeDuration) -> Result<(), Self::Error>;
574 fn write_alt_record(
576 &mut self,
577 _ty: &PsqlType,
578 _value: &ValueWithType<'_, ProductValue>,
579 ) -> Result<bool, Self::Error> {
580 Ok(false)
581 }
582
583 fn write_record(
584 &mut self,
585 fields: Vec<(Cow<str>, PsqlType, ValueWithType<AlgebraicValue>)>,
586 ) -> Result<(), Self::Error>;
587
588 fn write_variant(
589 &mut self,
590 tag: u8,
591 ty: PsqlType,
592 name: Option<&str>,
593 value: ValueWithType<AlgebraicValue>,
594 ) -> Result<(), Self::Error>;
595}
596
597pub struct TypedArrayFormatter<'a, 'f, F> {
599 ty: &'a PsqlType<'a>,
600 f: &'f mut F,
601}
602
603impl<F: TypedWriter> ser::SerializeArray for TypedArrayFormatter<'_, '_, F> {
604 type Ok = ();
605 type Error = F::Error;
606
607 fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
608 elem.serialize(TypedSerializer { ty: self.ty, f: self.f })?;
609 Ok(())
610 }
611
612 fn end(self) -> Result<Self::Ok, Self::Error> {
613 Ok(())
614 }
615}
616
617pub struct TypedSeqFormatter<'a, 'f, F> {
619 ty: &'a PsqlType<'a>,
620 f: &'f mut F,
621}
622
623impl<F: TypedWriter> ser::SerializeSeqProduct for TypedSeqFormatter<'_, '_, F> {
624 type Ok = ();
625 type Error = F::Error;
626
627 fn serialize_element<T: ser::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
628 elem.serialize(TypedSerializer { ty: self.ty, f: self.f })?;
629 Ok(())
630 }
631
632 fn end(self) -> Result<Self::Ok, Self::Error> {
633 Ok(())
634 }
635}
636
637pub struct TypedNamedProductFormatter<F> {
639 f: PhantomData<F>,
640}
641
642impl<F: TypedWriter> ser::SerializeNamedProduct for TypedNamedProductFormatter<F> {
643 type Ok = ();
644 type Error = F::Error;
645
646 fn serialize_element<T: ser::Serialize + ?Sized>(
647 &mut self,
648 _name: Option<&str>,
649 _elem: &T,
650 ) -> Result<(), Self::Error> {
651 Ok(())
652 }
653
654 fn end(self) -> Result<Self::Ok, Self::Error> {
655 Ok(())
656 }
657}
658
659pub struct TypedSerializer<'a, 'f, F> {
661 pub ty: &'a PsqlType<'a>,
662 pub f: &'f mut F,
663}
664
665impl<'a, 'f, F: TypedWriter> ser::Serializer for TypedSerializer<'a, 'f, F> {
666 type Ok = ();
667 type Error = F::Error;
668 type SerializeArray = TypedArrayFormatter<'a, 'f, F>;
669 type SerializeSeqProduct = TypedSeqFormatter<'a, 'f, F>;
670 type SerializeNamedProduct = TypedNamedProductFormatter<F>;
671
672 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
673 self.f.write_bool(v)
674 }
675
676 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
677 self.f.write(v)
678 }
679
680 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
681 self.f.write(v)
682 }
683
684 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
685 self.f.write(v)
686 }
687
688 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
689 self.f.write(v)
690 }
691
692 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
693 match self.ty.use_fmt() {
694 PsqlPrintFmt::Hex => self.f.write_hex(&v.to_be_bytes()),
695 _ => self.f.write(v),
696 }
697 }
698
699 fn serialize_u256(self, v: u256) -> Result<Self::Ok, Self::Error> {
700 match self.ty.use_fmt() {
701 PsqlPrintFmt::Hex => self.f.write_hex(&v.to_be_bytes()),
702 _ => self.f.write(v),
703 }
704 }
705
706 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
707 self.f.write(v)
708 }
709
710 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
711 self.f.write(v)
712 }
713
714 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
715 self.f.write(v)
716 }
717
718 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
719 match self.ty.use_fmt() {
720 PsqlPrintFmt::Duration => self.f.write_duration(TimeDuration::from_micros(v)),
721 PsqlPrintFmt::Timestamp => self.f.write_timestamp(Timestamp::from_micros_since_unix_epoch(v)),
722 _ => self.f.write(v),
723 }
724 }
725
726 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
727 self.f.write(v)
728 }
729
730 fn serialize_i256(self, v: i256) -> Result<Self::Ok, Self::Error> {
731 self.f.write(v)
732 }
733
734 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
735 self.f.write(v)
736 }
737
738 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
739 self.f.write(v)
740 }
741
742 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
743 self.f.write_string(v)
744 }
745
746 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
747 if self.ty.use_fmt() == PsqlPrintFmt::Satn {
748 self.f.write_hex(v)
749 } else {
750 self.f.write_bytes(v)
751 }
752 }
753
754 fn serialize_array(self, _len: usize) -> Result<Self::SerializeArray, Self::Error> {
755 Ok(TypedArrayFormatter { ty: self.ty, f: self.f })
756 }
757
758 fn serialize_seq_product(self, _len: usize) -> Result<Self::SerializeSeqProduct, Self::Error> {
759 Ok(TypedSeqFormatter { ty: self.ty, f: self.f })
760 }
761
762 fn serialize_named_product(self, _len: usize) -> Result<Self::SerializeNamedProduct, Self::Error> {
763 unreachable!("This should never be called, use `serialize_named_product_raw` instead.");
764 }
765
766 fn serialize_named_product_raw(self, value: &ValueWithType<'_, ProductValue>) -> Result<Self::Ok, Self::Error> {
767 let val = &value.val.elements;
768 assert_eq!(val.len(), value.ty().elements.len());
769 if self.ty.use_fmt().is_special() {
771 let (tuple, field) = if let Some(product) = self.ty.field.algebraic_type.as_product() {
774 (product, &product.elements[0])
775 } else {
776 (self.ty.tuple, self.ty.field)
777 };
778 return value.val.serialize(TypedSerializer {
779 ty: &PsqlType {
780 client: self.ty.client,
781 tuple,
782 field,
783 idx: self.ty.idx,
784 },
785 f: self.f,
786 });
787 }
788 if self.f.write_alt_record(self.ty, value)? {
790 return Ok(());
791 }
792 let mut record = Vec::with_capacity(val.len());
793
794 for (idx, (val, field)) in val.iter().zip(&*value.ty().elements).enumerate() {
795 let ty = PsqlType {
796 client: self.ty.client,
797 tuple: value.ty(),
798 field,
799 idx,
800 };
801 record.push((
802 field
803 .name()
804 .map(Cow::from)
805 .unwrap_or_else(|| Cow::from(format!("col_{idx}"))),
806 ty,
807 value.with(&field.algebraic_type, val),
808 ));
809 }
810 self.f.write_record(record)
811 }
812
813 fn serialize_variant_raw(self, sum: &ValueWithType<'_, SumValue>) -> Result<Self::Ok, Self::Error> {
814 let sv = sum.value();
815 let (tag, val) = (sv.tag, &*sv.value);
816 let var_ty = &sum.ty().variants[tag as usize]; let product = ProductType::from([AlgebraicType::sum(sum.ty().clone())]);
818 let ty = PsqlType {
819 client: self.ty.client,
820 tuple: &product,
821 field: &product.elements[0],
822 idx: 0,
823 };
824 self.f
825 .write_variant(tag, ty, var_ty.name(), sum.with(&var_ty.algebraic_type, val))
826 }
827
828 fn serialize_variant<T: Serialize + ?Sized>(
829 self,
830 _tag: u8,
831 _name: Option<&str>,
832 _value: &T,
833 ) -> Result<Self::Ok, Self::Error> {
834 unreachable!("Use `serialize_variant_raw` instead.");
835 }
836}
837
838impl TypedWriter for SqlFormatter<'_, '_> {
839 type Error = SatnError;
840
841 fn write<W: fmt::Display>(&mut self, value: W) -> Result<(), Self::Error> {
842 write!(self.fmt, "{value}")
843 }
844
845 fn write_bool(&mut self, value: bool) -> Result<(), Self::Error> {
846 write!(self.fmt, "{value}")
847 }
848
849 fn write_string(&mut self, value: &str) -> Result<(), Self::Error> {
850 write!(self.fmt, "\"{value}\"")
851 }
852
853 fn write_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
854 self.write_hex(value)
855 }
856
857 fn write_hex(&mut self, value: &[u8]) -> Result<(), Self::Error> {
858 match self.ty.client {
859 PsqlClient::SpacetimeDB => write!(self.fmt, "0x{}", hex::encode(value)),
860 PsqlClient::Postgres => write!(self.fmt, "\"0x{}\"", hex::encode(value)),
861 }
862 }
863
864 fn write_timestamp(&mut self, value: Timestamp) -> Result<(), Self::Error> {
865 match self.ty.client {
866 PsqlClient::SpacetimeDB => write!(self.fmt, "{}", value.to_rfc3339().unwrap()),
867 PsqlClient::Postgres => write!(self.fmt, "\"{}\"", value.to_rfc3339().unwrap()),
868 }
869 }
870
871 fn write_duration(&mut self, value: TimeDuration) -> Result<(), Self::Error> {
872 match self.ty.client {
873 PsqlClient::SpacetimeDB => write!(self.fmt, "{value}"),
874 PsqlClient::Postgres => write!(self.fmt, "\"{}\"", value.to_iso8601()),
875 }
876 }
877
878 fn write_record(
879 &mut self,
880 fields: Vec<(Cow<str>, PsqlType<'_>, ValueWithType<AlgebraicValue>)>,
881 ) -> Result<(), Self::Error> {
882 let PsqlChars { start, sep, end, quote } = self.ty.client.format_chars();
883 write!(self.fmt, "{start}")?;
884 for (idx, (name, ty, value)) in fields.into_iter().enumerate() {
885 if idx > 0 {
886 write!(self.fmt, ", ")?;
887 }
888 write!(self.fmt, "{quote}{name}{quote}{sep} ")?;
889
890 value.serialize(TypedSerializer { ty: &ty, f: self })?;
892 }
893 write!(self.fmt, "{end}")?;
894 Ok(())
895 }
896
897 fn write_variant(
898 &mut self,
899 tag: u8,
900 ty: PsqlType,
901 name: Option<&str>,
902 value: ValueWithType<AlgebraicValue>,
903 ) -> Result<(), Self::Error> {
904 self.write_record(vec![(
905 name.map(Cow::from).unwrap_or_else(|| Cow::from(format!("col_{tag}"))),
906 ty,
907 value,
908 )])
909 }
910}