#[doc(hidden)]
pub use linkme as __linkme;
#[doc(hidden)]
pub use rmp_serde as __rmp_serde;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ManifestKind {
Object,
Edge,
}
#[derive(Debug, Clone, Copy)]
pub struct TypeManifestEntry {
pub kind: ManifestKind,
pub type_name: &'static str,
pub from_type: Option<&'static str>,
pub to_type: Option<&'static str>,
}
#[linkme::distributed_slice]
pub static MANIFEST: [TypeManifestEntry];
pub fn object_types() -> impl Iterator<Item = &'static str> {
MANIFEST
.iter()
.filter(|e| matches!(e.kind, ManifestKind::Object))
.map(|e| e.type_name)
}
pub fn edge_entries() -> impl Iterator<Item = &'static TypeManifestEntry> {
MANIFEST
.iter()
.filter(|e| matches!(e.kind, ManifestKind::Edge))
}
pub fn object_types_sorted() -> Vec<&'static str> {
let mut v: Vec<&'static str> = object_types().collect();
v.sort_unstable();
v.dedup();
v
}
pub fn edge_entries_sorted() -> Vec<&'static TypeManifestEntry> {
let mut v: Vec<&'static TypeManifestEntry> = edge_entries().collect();
v.sort_unstable_by(|a, b| {
a.type_name
.cmp(b.type_name)
.then_with(|| a.from_type.cmp(&b.from_type))
.then_with(|| a.to_type.cmp(&b.to_type))
});
v.dedup_by(|a, b| {
a.type_name == b.type_name && a.from_type == b.from_type && a.to_type == b.to_type
});
v
}
pub fn render_json() -> String {
let mut out = String::new();
out.push_str("{\n \"objects\": [");
let objs = object_types_sorted();
for (i, name) in objs.iter().enumerate() {
if i > 0 {
out.push_str(", ");
}
out.push('"');
out.push_str(name);
out.push('"');
}
out.push_str("],\n \"edges\": [");
let edges = edge_entries_sorted();
for (i, e) in edges.iter().enumerate() {
if i > 0 {
out.push_str(", ");
}
out.push_str("{\"type\": \"");
out.push_str(e.type_name);
out.push_str("\", \"from\": \"");
out.push_str(e.from_type.unwrap_or(""));
out.push_str("\", \"to\": \"");
out.push_str(e.to_type.unwrap_or(""));
out.push_str("\"}");
}
out.push_str("]\n}\n");
out
}