I have a RwLock
protected global WORLD
, and I want to write a function that read locks it and returns an iterator (of type Neighbors
) that iterates over edges in a petgraph::stable_graph::StableGraph
that is stored inside the global. I'm using OwningRef
to deal with keeping the read lock guard alive after the function exits, which has worked for me in the past when just returning a field of World
directly. I've included a compilable example and the error I'm getting below -- it seems there is some sort of type problem but I haven't been able to figure it out. I think it might have to do with OwningRef
wanting to deal with a reference rather than an object containing a reference (Neighbors
) but I'm not sure how to work around that.
Cargo.toml:
[package]
name = "problem_demo"
version = "0.1.0"
authors = ["Joseph Garvin <joseph.h.garvin@gmail.com>"]
edition = "2018"
[dependencies]
owning_ref="0.4.1"
once_cell="1.4.0"
petgraph={version="0.5.1", features=["serde-1"]}
main.rs:
use std::{sync::RwLock};
use once_cell::sync::OnceCell;
use owning_ref::RwLockReadGuardRef;
use petgraph::stable_graph::{StableGraph, Neighbors};
struct Bar {
data: i32
}
struct World {
graph: StableGraph<(), Bar, petgraph::Directed, u32>
}
pub static WORLD: OnceCell<RwLock<World>> = OnceCell::new();
fn neighbors(id: u32) -> Result<RwLockReadGuardRef<'static, World, Neighbors<'static, Bar, u32>>, Box<dyn std::error::Error>> {
RwLockReadGuardRef::new(WORLD.get().unwrap().read().unwrap())
.try_map(
|world: &World| -> std::result::Result<Neighbors<'static, Bar, u32>, Box<dyn std::error::Error>>
{
let neighbors = world.graph.neighbors_directed(
petgraph::graph::NodeIndex::new(id as usize),
petgraph::Direction::Outgoing
);
Ok(neighbors)
}
)
}
Errors:
error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:21:13: 29:14 id:_] as std::ops::FnOnce<(&'r World,)>>::Output == std::result::Result<&'r _, _>`
--> src/main.rs:20:10
|
20 | .try_map(
| ^^^^^^^ expected struct `petgraph::stable_graph::Neighbors`, found reference
|
= note: expected enum `std::result::Result<petgraph::stable_graph::Neighbors<'static, Bar>, std::boxed::Box<dyn std::error::Error>>`
found enum `std::result::Result<&_, _>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.