Check out the graph-api book for more information.
This library offers a unified interface for working with different types of graphs while maintaining strong type safety and ergonomic usage patterns. It includes features for graph traversal, modification, and custom extensions.
- Type-safe graph operations
- Flexible vertex and edge traversal
- Custom graph implementations support
- Derive macros for extending graph functionality
- Comprehensive testing utilities including fuzzing support
#[derive(Debug, Clone, VertexExt)]
pub enum Vertex {
Person {
#[index(hash)]
name: String,
#[index(range)]
age: u64,
#[index(hash)]
unique_id: Uuid,
#[index(range)]
username: String,
#[index(full_text)]
biography: String,
},
Project {
name: String
},
Rust,
}
#[derive(Debug, Clone, EdgeExt)]
pub enum Edge {
Knows { since: i32 },
Created,
Language {
name: String
},
}
fn main() {
// Create a new graph
let mut graph = SimpleGraph::new();
// Populate the graph
let person = graph.add_vertex(Vertex::Person {
name: "Bryn".to_string(),
age: 45,
unique_id: Uuid::from_u128(1),
username: "bryn".to_string(),
biography: "Did some graph stuff".to_string(),
});
let project = graph.add_vertex(Vertex::Project { name: "Graph API".to_string() });
graph.add_edge(person, project, Edge::Created);
// Traverse the graph
let all_vertices = graph.walk().vertices(VertexSearch::scan()).collect::<Vec<_>>();
// A more complicated traversal
// For up to two people that Bryn knows find all the people that they know and add
// their ages to Bryn's age and collect them into a list.
let complex = graph
.walk()
.vertices(VertexIndex::person_by_name("Bryn")) // Start at people named Bryn
.filter_by_person(|v, _| v.username().ends_with("e")) // Filter by username ending with e
.push_context(|v, ctx| v.project::<Person<_>>().unwrap().age()) // Stash the age in the context
.edges(EdgeIndex::knows().direction(Direction::Outgoing)) // Traverse to knows
.limit(2) // Limit the traversal to two elements
.head() // Traverse to the head of the edge (the known person)
.detour(|v| { // Find the people that this person knows and collect their ages
v.edges(EdgeIndex::knows().direction(Direction::Outgoing))
.head()
.push_context(|v, ctx| v.project::<Person<_>>().unwrap().age())
})
.map(|v, ctx| **ctx.parent() + *ctx) // Add the ages collected during the traversal
.collect::<Vec<_>>();
}
Head over to the graph-api book.
Contributions are welcome! Please check out our contribution guidelines for details on how to get started.