I'm trying to create a petgraph Graph
from JSON data. The JSON contains the edges of the graph, the key represents the starting vertex and the value is a list of adjacent vertices. It's possible to generate a graph with a vector of edges.
I managed to create a Vec<(String, String))>
but not a Vec<(&str, &str)>
as expected.
extern crate petgraph;
extern crate serde_json;
use petgraph::prelude::*;
use serde_json::{Value, Error};
fn main() {
let data = r#"{
"A": [ "B" ],
"B": [ "C", "D" ],
"D": [ "E", "F" ]
}"#;
let json_value: Value = serde_json::from_str(data).unwrap();
let mut edges: Vec<(String, String)> = vec![];
if let Value::Object(map) = json_value {
for (from_edge, array) in &map {
if let &Value::Array(ref array_value) = array {
for edge in array_value {
if let &Value::String(ref to_edge) = edge {
edges.push((from_edge.clone(), to_edge.clone()))
}
}
}
}
}
// let graph = DiGraphMap::<&str, ()>::from_edges(edges);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct
// `std::string::String`, found &str
}
I tried different things:
- Change the graph type to
DiGraphMap::<String, ()>
, however it does not accept it. - Transform a
Vec<(String, String)>
into aVec<(&str, &str)>
. I read this post but it didn't help. edges.push((&"a", &"b"))
works but notedges.push((&from.clone(), &to.clone()))
.
There is probably a better way to extract the edges here.
A
GraphMap
requires that the node type be copyable.String
does not implementCopy
.As mentioned in the question you linked, this is impossible. What you can do is create a second
Vec
with&str
that reference the originalString
s:However, that's not needed in this case. Instead, read the JSON data into a data structure that models a map (I chose
BTreeMap
) and leave theString
s there. You can then construct an iterator of pairs of references to thoseString
s, building the graph from that:This is barely possible to do. Since JSON strings contain UTF-8 data, Serde allows you to get references to original input strings. You need to remember that your
graph
cannot outliveinput
: