use std::cmp::Ordering;
use std::fmt::Display;
use std::str::FromStr;
use crate::core::ArrayBuilder;
use crate::core::ObjectBuilder;
use crate::core::Serializer;
use crate::error::Error;
use crate::error::Result;
use crate::parse_value;
use crate::RawJsonb;
#[derive(Debug, Clone)]
pub struct OwnedJsonb {
pub(crate) data: Vec<u8>,
}
impl OwnedJsonb {
pub fn new(data: Vec<u8>) -> OwnedJsonb {
Self { data }
}
pub fn as_raw(&self) -> RawJsonb<'_> {
RawJsonb::new(self.data.as_slice())
}
pub fn to_vec(self) -> Vec<u8> {
self.data
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn build_array<'a>(
raw_jsonbs: impl IntoIterator<Item = RawJsonb<'a>>,
) -> Result<OwnedJsonb> {
let mut builder = ArrayBuilder::new();
for raw_jsonb in raw_jsonbs.into_iter() {
builder.push_raw_jsonb(raw_jsonb);
}
builder.build()
}
pub fn build_object<'a, K: AsRef<str>>(
items: impl IntoIterator<Item = (K, RawJsonb<'a>)>,
) -> Result<OwnedJsonb> {
let mut kvs = Vec::new();
for (key, val) in items.into_iter() {
kvs.push((key, val));
}
let mut builder = ObjectBuilder::new();
for (key, val) in kvs.iter() {
builder.push_raw_jsonb(key.as_ref(), *val)?;
}
builder.build()
}
}
impl From<&[u8]> for OwnedJsonb {
fn from(data: &[u8]) -> Self {
Self {
data: data.to_vec(),
}
}
}
impl From<Vec<u8>> for OwnedJsonb {
fn from(data: Vec<u8>) -> Self {
Self { data }
}
}
impl FromStr for OwnedJsonb {
type Err = Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let value = parse_value(s.as_bytes())?;
let mut data = Vec::new();
value.write_to_vec(&mut data);
Ok(Self { data })
}
}
impl AsRef<[u8]> for OwnedJsonb {
fn as_ref(&self) -> &[u8] {
self.data.as_ref()
}
}
impl Display for OwnedJsonb {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let raw_jsonb = self.as_raw();
write!(f, "{}", raw_jsonb.to_string())
}
}
impl Eq for OwnedJsonb {}
impl PartialEq for OwnedJsonb {
fn eq(&self, other: &Self) -> bool {
self.partial_cmp(other) == Some(Ordering::Equal)
}
}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for OwnedJsonb {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let self_raw = self.as_raw();
let other_raw = other.as_raw();
self_raw.partial_cmp(&other_raw)
}
}
impl Ord for OwnedJsonb {
fn cmp(&self, other: &Self) -> Ordering {
let self_raw = self.as_raw();
let other_raw = other.as_raw();
match self_raw.partial_cmp(&other_raw) {
Some(ordering) => ordering,
None => Ordering::Equal,
}
}
}
pub fn to_owned_jsonb<T>(value: &T) -> Result<OwnedJsonb>
where
T: serde::ser::Serialize,
{
let mut serializer = Serializer::default();
value.serialize(&mut serializer)?;
Ok(serializer.to_owned_jsonb())
}