Unfortunately I'm unable to implement Debug trait by myself. Hence I'm looking for help here.
use std::{collections::HashMap, fmt::Debug};
lazy_static! {
pub static ref REGION_LOCATION: HashMap<&'static str, Vec<&'static str>> = [
("de", vec!["fra", "txl"]),
("us", vec!["las", "ewr"]),
("gb", vec!["lhr"])
]
.iter()
.cloned()
.collect();
}
impl std::fmt::Debug for REGION_LOCATION {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut inner: Vec<String> = Vec::with_capacity(REGION_LOCATION.len());
for (key, val) in REGION_LOCATION.iter() {
let l = val.join(", ");
let item = format!("{{{}: [{}]}}", key, l).to_owned();
inner.push(item.to_owned());
}
std::fmt::Debug::fmt(inner.as_ref(), f)
}
}
The compiler asked for type annotatons, but I a newbie don't now how to do that. Could one more experienced developer help me to solve the issue?
error[E0283]: type annotations needed
--> src/ionos/cloud/api/v5/locations.rs:22:9
|
22 | std::fmt::Debug::fmt(inner.as_ref(), f)
| ^^^^^^^^^^^^^^^^^^^^ -------------- this method call resolves to `&T`
| |
| cannot infer type
|
= note: cannot satisfy `_: Debug`
= note: required by `std::fmt::Debug::fmt`
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0283`.
First off, you don't implement a trait for a specific value. You implement it for a type, and it'll apply to all instances of that type. (That's kind of the whole point of having types: treating sets of values uniformly, independent of their actual run-time value.)
So, you'd want to impl Debug for HashMap<K, V> instead. But you can't, because:
it's already implemented (look at the docs!), and
even if it weren't implemented, you wouldn't be allowed to implement it, because neither HashMap nor Debug is defined by your code (so if any 3rd-party code could implement it, there would be bad problems – google "coherence" if you want to know the details).
Yes, however, you're still not implementing the trait for the value; the macro apparently generates a type with the same name as the value. So there's a global static named REGION_LOCATION, and there's also a type called REGION_LOCATION. This is confusing because ALL_CAPS is not the convention for Rust types, but it's permitted.
Anyway, I just noticed that the "type annotations needed" compiler error is valid, too (as opposed to it being a red herring due to type checking going wrong somewhere else, as I initially thought). The issue there is that Vec::as_ref can be interpreted in two different ways. There's an impl AsRef<[T]> for Vec<T>, but there's also a blanket impl AsRef<T> for T. So the compiler can't decide which one to pick. You should probably use .as_slice() instead.
Technically - nothing. You just have to remember that REGION_LOCATION here is not a map, but a singleton wrapper around this map. And, if you remove as_ref and just use &inner, this actually works - playground.