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