Hey, hoping someone can help me out. I have reduced my issue to the smallest possible code:
use std::collections::HashMap;
use std::fmt::Debug;
trait Walkable {
fn walk(&self, segment: &str) -> Result<&dyn Walkable, String>;
}
impl<I: Walkable> Walkable for HashMap<&str, I> {
fn walk(&self, segment: &str) -> Result<&dyn Walkable, String> {
// Does not work:
// self.get(segment).ok_or("failed".to_string())
// Works:
match self.get(segment) {
Some(v) => Ok(v),
None => Err("failed".to_string()),
}
}
}
So the general idea is I'm trying to create a trait to handle generically walking down a tree. So like:
context = {"cat": {"food": {"good": "meat", "bad": "pizza"}}}
context.walk("cat").walk("food") would return {"good": "meat", "bad": "pizza"}
So I'm trying to create a generic implementation of this Walkable for Hashmap. My problem comes when I'm trying to use ok_or. As you can see in the code block above, when I do the match statement manually, everything works fine. But if I comment out the match statement and uncomment the ok_or line it does not work. The thing is, I've looking through the implementation for ok_or() and I can't seem the find the difference between the two. My reasoning is:
self is a HashMap<&str, I>
I is a Walkable
Therefor self is a HashMap<&str, Walkable>
HashMap::get returns a Option<&V> so therefore an Option<&Walkable>
ok_or is implemented as:
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
match self {
Some(v) => Ok(v),
None => Err(err),
}
}
Which appears to be identical to my working match statement. Filling in the types of &Walkable from the Option and String for the error we'd get:
pub fn ok_or<E>(self, err: String) -> Result<&Walkable, String> {
match self {
Some(v: &Walkable) => Ok(v),
None => Err(err),
}
}