use std::collections::BTreeMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EdgeId(pub u64);
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum PropertyValue {
Null,
Bool(bool),
Int(i64),
Float(f64),
String(String),
Date(i32),
Duration {
months: i64,
days: i64,
seconds: i64,
nanos: i32,
},
LocalTime(i64),
Time {
nanos_of_day: i64,
offset_seconds: i32,
},
LocalDateTime {
epoch_seconds: i64,
nanos: i32,
},
DateTime {
epoch_seconds: i64,
nanos: i32,
zone: TzId,
},
List(Vec<PropertyValue>),
Map(BTreeMap<String, PropertyValue>),
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum TzId {
Offset(i32),
Named(String),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Node {
pub id: NodeId,
pub labels: Vec<String>,
pub props: BTreeMap<String, PropertyValue>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Edge {
pub id: EdgeId,
pub label: String,
pub src: NodeId,
pub dst: NodeId,
pub props: BTreeMap<String, PropertyValue>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
Out,
In,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AdjEntry {
pub edge_id: EdgeId,
pub other: NodeId,
pub label_id: u32,
}
impl AdjEntry {
pub(crate) fn encode(&self) -> [u8; 20] {
let mut buf = [0u8; 20];
buf[0..8].copy_from_slice(&self.edge_id.0.to_be_bytes());
buf[8..16].copy_from_slice(&self.other.0.to_be_bytes());
buf[16..20].copy_from_slice(&self.label_id.to_be_bytes());
buf
}
pub(crate) fn decode(bytes: &[u8]) -> Result<Self, crate::GraphError> {
let bytes: &[u8; 20] = bytes.try_into().map_err(|_| {
crate::GraphError::CorruptData(format!(
"adjacency entry has {} bytes; expected 20",
bytes.len()
))
})?;
let edge_id = u64::from_be_bytes(bytes[0..8].try_into().expect("fixed-size slice"));
let other = u64::from_be_bytes(bytes[8..16].try_into().expect("fixed-size slice"));
let label_id = u32::from_be_bytes(bytes[16..20].try_into().expect("fixed-size slice"));
Ok(AdjEntry {
edge_id: EdgeId(edge_id),
other: NodeId(other),
label_id,
})
}
}