Reputation: 463
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.
Upvotes: 1
Views: 63
Reputation: 13750
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
.
Upvotes: 2