mz_pgrepr/value/
jsonb.rs

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.
9
10use std::error::Error;
11use std::fmt;
12
13use bytes::{BufMut, BytesMut};
14use postgres_types::{FromSql, IsNull, ToSql, Type, to_sql_checked};
15
16/// 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);
21
22impl ToSql for Jsonb {
23    fn 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
29        self.0.as_ref().to_writer(out.writer())?;
30        Ok(IsNull::No)
31    }
32
33    fn accepts(ty: &Type) -> bool {
34        matches!(*ty, Type::JSONB)
35    }
36
37    to_sql_checked!();
38}
39
40impl<'a> FromSql<'a> for Jsonb {
41    fn from_sql(_: &Type, raw: &'a [u8]) -> Result<Jsonb, Box<dyn Error + Sync + Send>> {
42        if raw.len() < 1 || raw[0] != 1 {
43            return Err("unsupported jsonb encoding version".into());
44        }
45        Ok(Jsonb(mz_repr::adt::jsonb::Jsonb::from_slice(&raw[1..])?))
46    }
47
48    fn accepts(ty: &Type) -> bool {
49        matches!(*ty, Type::JSONB)
50    }
51}
52
53impl fmt::Display for Jsonb {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        self.0.fmt(f)
56    }
57}