use std::collections::HashMap;
use nodedb_types::Value;
const EDGE_ID_SEP: char = '\u{1}';
pub(crate) const GRAPH_LABEL_STREAM: &str = "__graph_node_labels__";
pub(crate) fn edge_row_id(src: &str, label: &str, dst: &str) -> String {
let mut id = String::with_capacity(src.len() + label.len() + dst.len() + 2);
id.push_str(src);
id.push(EDGE_ID_SEP);
id.push_str(label);
id.push(EDGE_ID_SEP);
id.push_str(dst);
id
}
pub(crate) fn graph_label_delta_value(labels: &[String]) -> Vec<u8> {
let arr = Value::Array(labels.iter().map(|l| Value::String(l.clone())).collect());
let mut obj = HashMap::with_capacity(1);
obj.insert("labels".to_string(), arr);
nodedb_types::value_to_msgpack(&Value::Object(obj)).unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn edge_row_id_is_stable_and_separated() {
assert_eq!(edge_row_id("a", "KNOWS", "b"), "a\u{1}KNOWS\u{1}b");
}
#[test]
fn edge_row_id_distinguishes_components() {
assert_ne!(edge_row_id("ab", "K", "c"), edge_row_id("a", "bK", "c"));
}
#[test]
fn label_delta_value_round_trips_as_object() {
let bytes = graph_label_delta_value(&["Person".to_string(), "User".to_string()]);
let map = crate::event::deserialize_event_payload(&bytes)
.expect("label delta must decode as a JSON object");
let labels = map
.get("labels")
.and_then(|v| v.as_array())
.expect("labels array present");
let got: Vec<&str> = labels.iter().filter_map(|v| v.as_str()).collect();
assert_eq!(got, vec!["Person", "User"]);
}
#[test]
fn label_stream_name_has_no_nul() {
assert!(!GRAPH_LABEL_STREAM.contains('\0'));
assert_eq!(GRAPH_LABEL_STREAM, "__graph_node_labels__");
}
}