use std::ops::Index;
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Null,
Bool(bool),
Int64(i64),
Float64(f64),
Str(String),
Bytes(Vec<u8>),
Uuid(uuid::Uuid),
Decimal(String),
Duration {
months: i32,
days: i32,
microseconds: i64,
},
Date(i32),
Time(i64),
Timestamp(i64),
Timestamptz(i64),
Range(Box<Range>),
Array(Vec<Value>),
Tuple(Vec<Value>),
Object(Object),
Enum {
type_name: String,
value: String,
},
Group(Box<Group>),
VectorSearch {
object: Box<Value>,
distance: f64,
},
FtsSearch {
object: Box<Value>,
score: f64,
},
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Object {
pub(crate) type_name: Option<String>,
pub(crate) fields: Vec<(String, Value)>,
pub(crate) implicit_id: bool,
}
impl Object {
pub fn type_name(&self) -> Option<&str> {
self.type_name.as_deref()
}
pub fn fields(&self) -> impl Iterator<Item = (&str, &Value)> {
self.fields.iter().map(|(n, v)| (n.as_str(), v))
}
pub fn json_fields(&self) -> impl Iterator<Item = (&str, &Value)> {
let skip = usize::from(self.implicit_id);
self.fields.iter().skip(skip).map(|(n, v)| (n.as_str(), v))
}
pub fn get(&self, name: &str) -> Option<&Value> {
self.fields.iter().find(|(n, _)| n == name).map(|(_, v)| v)
}
pub fn len(&self) -> usize {
self.fields.len()
}
pub fn is_empty(&self) -> bool {
self.fields.is_empty()
}
}
impl Index<&str> for Object {
type Output = Value;
fn index(&self, name: &str) -> &Value {
self.get(name).unwrap_or_else(|| panic!("Object has no field {name:?}"))
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Range {
pub lower: Option<Value>,
pub upper: Option<Value>,
pub inc_lower: bool,
pub inc_upper: bool,
pub empty: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Group {
pub key: Object,
pub grouping: Vec<String>,
pub elements: Vec<Value>,
}