I am trying to write a generic method that accepts a function that returns either a Serialize
value or an Arc<Serialize>
value. My solution is to create a trait to unwrap the Arc
if needed and produce a reference to the underlying value:
use serde::Serialize;
use std::sync::Arc;
pub trait Unwrapper {
type Inner: Serialize;
fn unwrap(&self) -> &Self::Inner;
}
impl<T> Unwrapper for T
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
impl<T> Unwrapper for Arc<T>
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
fn use_processor<F, O>(processor: F)
where
O: Unwrapper,
F: Fn() -> O,
{
// do something useful processor
}
I get a E0119
error due to the potential that Arc
may implement Serialize
in the future, like if I enable the serde crate's feature to allow just that:
error[E0119]: conflicting implementations of trait `Unwrapper` for type `std::sync::Arc<_>`:
--> src/lib.rs:20:1
|
10 | / impl<T> Unwrapper for T
11 | | where
12 | | T: Serialize,
13 | | {
... |
17 | | }
18 | | }
| |_- first implementation here
19 |
20 | / impl<T> Unwrapper for Arc<T>
21 | | where
22 | | T: Serialize,
23 | | {
... |
27 | | }
28 | | }
| |_^ conflicting implementation for `std::sync::Arc<_>`
I don't want to do this as I only want to allow the Arc
at the top level and not within the value (for the same reasons the feature is not on by default). Given this, Is there a way to disable my first impl
only for an Arc
? Or is there a better approach to the to problem?