spacetimedb_sats/
satn.rs

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
11/// An extension trait for [`Serialize`] providing formatting methods.
12pub trait Satn: ser::Serialize {
13    /// Formats the value using the SATN data format into the formatter `f`.
14    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15        Writer::with(f, |f| self.serialize(SatnFormatter { f }))?;
16        Ok(())
17    }
18
19    /// Formats the value using the postgres SATN(PsqlFormatter { f }, /* PsqlType */) formatter `f`.
20    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    /// Formats the value using the SATN data format into the returned `String`.
34    fn to_satn(&self) -> String {
35        Wrapper::from_ref(self).to_string()
36    }
37
38    /// Pretty prints the value using the SATN data format into the returned `String`.
39    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/// A wrapper around a `T: Satn`
47/// providing `Display` and `Debug` implementations
48/// that uses the SATN formatting for `T`.
49#[repr(transparent)]
50pub struct Wrapper<T: ?Sized>(pub T);
51
52impl<T: ?Sized> Wrapper<T> {
53    /// Converts `&T` to `&Wrapper<T>`.
54    pub fn from_ref(t: &T) -> &Self {
55        // SAFETY: `repr(transparent)` turns the ABI of `T`
56        // into the same as `Self` so we can also cast `&T` to `&Self`.
57        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
73/// A wrapper around a `T: Satn`
74/// providing `Display` and `Debug` implementations
75/// that uses postgres SATN formatting for `T`.
76pub struct PsqlWrapper<'a, T: ?Sized> {
77    pub ty: PsqlType<'a>,
78    pub value: T,
79}
80
81impl<T: ?Sized> PsqlWrapper<'_, T> {
82    /// Converts `&T` to `&PsqlWrapper<T>`.
83    pub fn from_ref(t: &T) -> &Self {
84        // SAFETY: `repr(transparent)` turns the ABI of `T`
85        // into the same as `Self` so we can also cast `&T` to `&Self`.
86        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
102/// Wraps a writer for formatting lists separated by `SEP` into it.
103struct EntryWrapper<'a, 'f, const SEP: char> {
104    /// The writer we're formatting into.
105    fmt: Writer<'a, 'f>,
106    /// Whether there were any fields.
107    /// Initially `false` and then `true` after calling [`.entry(..)`](EntryWrapper::entry).
108    has_fields: bool,
109}
110
111impl<'a, 'f, const SEP: char> EntryWrapper<'a, 'f, SEP> {
112    /// Constructs the entry wrapper using the writer `fmt`.
113    fn new(fmt: Writer<'a, 'f>) -> Self {
114        Self { fmt, has_fields: false }
115    }
116
117    /// Formats another entry in the larger structure.
118    ///
119    /// The formatting for the element / entry itself is provided by the function `entry`.
120    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
146/// An implementation of [`fmt::Write`] supporting indented and non-idented formatting.
147enum Writer<'a, 'f> {
148    /// Uses the standard library's formatter i.e. plain formatting.
149    Normal(&'a mut fmt::Formatter<'f>),
150    /// Uses indented formatting.
151    Pretty(IndentedWriter<'a, 'f>),
152}
153
154impl<'f> Writer<'_, 'f> {
155    /// Provided with a formatter `f`, runs `func` provided with a `Writer`.
156    fn with<R>(f: &mut fmt::Formatter<'_>, func: impl FnOnce(Writer<'_, '_>) -> R) -> R {
157        let mut state;
158        // We use `alternate`, i.e., the `#` flag to let the user trigger pretty printing.
159        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    /// Returns a sub-writer without moving `self`.
172    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
180/// A formatter that adds decoration atop of the standard library's formatter.
181struct IndentedWriter<'a, 'f> {
182    f: &'a mut fmt::Formatter<'f>,
183    state: &'a mut IndentState,
184}
185
186/// The indentation state.
187struct IndentState {
188    /// Number of tab indentations to make.
189    indent: u32,
190    /// Whether we were last on a newline.
191    on_newline: bool,
192}
193
194impl<'f> IndentedWriter<'_, 'f> {
195    /// Returns a sub-writer without moving `self`.
196    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                // Indent 4 characters times the indentation level.
209                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
230/// Provides the SATN data format implementing [`Serializer`](ser::Serializer).
231struct SatnFormatter<'a, 'f> {
232    /// The sink / writer / output / formatter.
233    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/// An error occurred during serialization to the SATS data format.
258#[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    /// Writes `args` formatted to `self`.
269    #[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, "[")?; // Closed via `.end()`.
339        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        // Delegate to named products handling of element formatting.
346        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, "(")?; // Closed via `.end()`.
351        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
367/// Defines the SATN formatting for arrays.
368struct ArrayFormatter<'a, 'f> {
369    /// The formatter for each element separating elements by a `,`.
370    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
388/// Provides the data format for unnamed products for SATN.
389struct SeqFormatter<'a, 'f> {
390    /// Delegates to the named format.
391    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
407/// Provides the data format for named products for SATN.
408struct NamedFormatter<'a, 'f> {
409    /// The formatter for each element separating elements by a `,`.
410    f: EntryWrapper<'a, 'f, ','>,
411    /// The index of the element.
412    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            // Format the name or use the index if unnamed.
426            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/// Which client is used to format the `SQL` output?
447#[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/// How format of the `SQL` output?
480#[derive(Debug, Copy, Clone, PartialEq, Display)]
481pub enum PsqlPrintFmt {
482    /// Print as `hex` format
483    Hex,
484    /// Print as [`Timestamp`] format
485    Timestamp,
486    /// Print as [`TimeDuration`] format
487    Duration,
488    /// Print as `Satn` format
489    Satn,
490}
491
492impl PsqlPrintFmt {
493    pub fn is_special(&self) -> bool {
494        self != &PsqlPrintFmt::Satn
495    }
496    /// Returns if the type is a special type
497    ///
498    /// Is required to check both the enclosing type and the inner element type
499    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/// A wrapper that remember the `header` of the tuple/struct and the current field
529#[derive(Debug, Clone)]
530pub struct PsqlType<'a> {
531    /// The client used to format the output
532    pub client: PsqlClient,
533    /// The header of the tuple/struct
534    pub tuple: &'a ProductType,
535    /// The current field
536    pub field: &'a ProductTypeElement,
537    /// The index of the field in the tuple/struct
538    pub idx: usize,
539}
540
541impl PsqlType<'_> {
542    /// Returns if the type is a special type
543    ///
544    /// Is required to check both the enclosing type and the inner element type
545    pub fn use_fmt(&self) -> PsqlPrintFmt {
546        PsqlPrintFmt::use_fmt(self.tuple, self.field, None)
547    }
548}
549
550/// An implementation of [`Serializer`](ser::Serializer) for `SQL` output.
551pub struct SqlFormatter<'a, 'f> {
552    fmt: SatnFormatter<'a, 'f>,
553    ty: &'a PsqlType<'a>,
554}
555
556/// A trait for writing values, after the special types has been determined.
557///
558/// This is used to write values that could have different representations depending on the output format,
559/// as defined by [`PsqlClient`] and [`PsqlPrintFmt`].
560pub trait TypedWriter {
561    type Error: ser::Error;
562
563    /// Writes a value using [`ser::Serializer`]
564    fn write<W: fmt::Display>(&mut self, value: W) -> Result<(), Self::Error>;
565
566    // Values that need special handling:
567
568    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    /// Writes a value as an alternative record format, e.g., for use `JSON` inside `SQL`.
575    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
597/// A formatter for arrays that uses the `TypedWriter` trait to write elements.
598pub 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
617/// A formatter for sequences that uses the `TypedWriter` trait to write elements.
618pub 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
637/// A formatter for named products that uses the `TypedWriter` trait to write elements.
638pub 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
659/// A serializer that uses the `TypedWriter` trait to serialize values
660pub 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 the value is a special type, we can write it directly
770        if self.ty.use_fmt().is_special() {
771            // Is a nested product type?
772            // We need to check for both the  enclosing(`self.ty`) type and the inner element type.
773            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        // Allow to switch to an alternative record format, for example to write a `JSON` record.
789        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]; // Extract the variant type by tag.
817        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            // Serialize the value
891            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}