1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
910use std::error::Error;
11use std::fmt;
1213use bytes::{BufMut, BytesMut};
14use postgres_types::{FromSql, IsNull, ToSql, Type, to_sql_checked};
1516/// A wrapper for the `repr` crate's [`Jsonb`](mz_repr::adt::jsonb::Jsonb) type
17/// that can be serialized to and deserialized from the PostgreSQL binary
18/// format.
19#[derive(Debug)]
20pub struct Jsonb(pub mz_repr::adt::jsonb::Jsonb);
2122impl ToSql for Jsonb {
23fn to_sql(
24&self,
25_: &Type,
26 out: &mut BytesMut,
27 ) -> Result<IsNull, Box<dyn Error + 'static + Send + Sync>> {
28 out.put_u8(1); // version
29self.0.as_ref().to_writer(out.writer())?;
30Ok(IsNull::No)
31 }
3233fn accepts(ty: &Type) -> bool {
34matches!(*ty, Type::JSONB)
35 }
3637to_sql_checked!();
38}
3940impl<'a> FromSql<'a> for Jsonb {
41fn from_sql(_: &Type, raw: &'a [u8]) -> Result<Jsonb, Box<dyn Error + Sync + Send>> {
42if raw.len() < 1 || raw[0] != 1 {
43return Err("unsupported jsonb encoding version".into());
44 }
45Ok(Jsonb(mz_repr::adt::jsonb::Jsonb::from_slice(&raw[1..])?))
46 }
4748fn accepts(ty: &Type) -> bool {
49matches!(*ty, Type::JSONB)
50 }
51}
5253impl fmt::Display for Jsonb {
54fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55self.0.fmt(f)
56 }
57}