I'm trying to create a wrapper on a graph of the petgraph
library and have run into the following issue. Here is a minimum repoduction:
use petgraph::{
data::Build,
graph::UnGraph,
visit::{IntoEdgeReferences, NodeIndexable},
Graph,
};
use std::fmt::Debug;
struct Wrap<G>
where
G: Build + IntoEdgeReferences + NodeIndexable,
G::EdgeRef: Debug,
G::EdgeWeight: Default,
{
graph: G,
}
impl<G> Wrap<G>
where
G: Build + IntoEdgeReferences + NodeIndexable,
G::EdgeRef: Debug,
G::EdgeWeight: Default,
{
fn new(graph: G) -> Self {
Self { graph }
}
fn insert_edge(&mut self, from: usize, to: usize) {
let from = self.graph.from_index(from);
let to = self.graph.from_index(to);
self.graph.add_edge(from, to, Default::default());
}
fn iter_edges(&self) {
self.graph.edge_references().for_each(|e| println!("{e:?}"));
}
}
#[test]
fn test() {
let graph: UnGraph<u32, u32> = UnGraph::new_undirected();
let wrap = Wrap::new(graph);
}
So the issue is that Build
is implemented on G
, however IntoEdgeReferences
is implemented on &'a G
, something I have, up until now, very rarely seen. I have made various attempts to fix this issue such as specifying traits for the reference:
&'a G: IntoEdgeReferences,
<&'a G as IntoEdgeReferences>::EdgeRef: Debug,
or (attempting to) implement Borrow
:
G: Borrow<H>,
H: IntoEdgeReferences
But I both feel that I am polluting my code with long, complicated trait bounds (much longer than in this example), and more importantly, find myself unsuccessful in compiling my code despite taking all advice from rust analyzer. Could someone give me some guidance on how I can handle a generic wrapper which needs bounds from owning, referenced and mutable references to the inner type?