I have a JSON collection that contains elements of a map that I would like to serialize back/forth to a list representation. This is the code I have written:
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{collections::HashMap, hash::Hash};
pub trait GetId<T>
{
fn get_id(&self) -> &T;
}
/// Serializable collection
#[derive(Serialize, Deserialize, Default, Clone)]
#[serde(from="Vec<V>", into="Vec<V>")]
pub struct Collection<K, V>
where K: Eq + Hash + Clone,
V: Serialize + DeserializeOwned + GetId<K> + Clone,
{
data: HashMap<K, V>,
}
impl<K, V> Collection<K, V>
where K: Eq + Hash + Clone,
V: Serialize + DeserializeOwned + GetId<K> + Clone,
{
pub fn new() -> Self {
Collection {
data: HashMap::new(),
}
}
pub fn insert(&mut self, item: V) -> Option<V> {
let id = item.get_id().to_owned();
self.data.insert(id, item)
}
}
impl<K, V> From<Vec<V>> for Collection<K, V>
where K: Eq + Hash + Clone,
V: Serialize + DeserializeOwned + GetId<K> + Clone,
{
fn from(value: Vec<V>) -> Self {
let mut obj: Collection<K, V> = Collection::new();
value.into_iter().for_each(|v| { obj.insert(v); });
obj
}
}
impl<K, V> Into<Vec<V>> for Collection<K, V>
where K: Eq + Hash + Clone,
V: Serialize + DeserializeOwned + GetId<K> + Clone,
{
fn into(self) -> Vec<V> {
Vec::from_iter(self.data.into_values())
}
}
I use the From<Vec<V>>
implementation and the GetKey<K>
trait to insert all the elements of the serialized Vec<V>
into the HashMap<K, V>
.
I'm having issues with the lifetimes here however, and am getting errors such as the below:
error[E0283]: type annotations needed: cannot satisfy `V: Deserialize<'_>`
--> src\idls\collection.rs:14:12
|
14 | pub struct Collection<K, V>
| ^^^^^^^^^^^^^^^^
|
note: multiple `impl`s or `where` clauses satisfying `V: Deserialize<'_>` found
--> src\idls\collection.rs:12:21
|
12 | #[derive(Serialize, Deserialize, Default, Clone)]
| ^^^^^^^^^^^
...
17 | V: Serialize + DeserializeOwned + GetId<K> + Clone,
| ^^^^^^^^^^^^^^^^
note: required for `Collection<K, V>` to implement `Deserialize<'de>`
--> src\idls\collection.rs:12:21
|
12 | #[derive(Serialize, Deserialize, Default, Clone)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
13 | #[serde(from="Vec<V>", into="Vec<V>")]
14 | pub struct Collection<K, V>
| ^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
I'm not familiar enough with Rust to understand what I'm doing wrong here. I read thru the Deserializer lifetimes docs that Serde provided, but I don't quite understand why these generics don't seem to be working. I've tried swapping DeserializeOwned
with for<'a> Deserialize<'a>
, but I don't believe that's correct for my use case, and also it doesn't work.
Deriving Serialize
and Deserialize
will automatically add the necessary trait bounds to generic parameters, so you should not write them yourself. So, just remove Serialize + DeserializeOwned
from the trait bounds on V
.