Я пытаюсь написать метод generic c, который принимает функцию, которая возвращает либо значение Serialize
, либо значение Arc<Serialize>
. Мое решение состоит в том, чтобы создать черту, чтобы развернуть Arc
при необходимости и создать ссылку на базовое значение:
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
}
Я получаю ошибку E0119
из-за потенциальной возможности реализации Arc
Serialize
в будущем, например, если я включу функцию ящика serde, чтобы разрешить только это:
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<_>`
Я не хочу делать это, поскольку я хочу только разрешить Arc
вверху уровень, а не в пределах значения (по тем же причинам функция не включена по умолчанию). Учитывая это, есть ли способ отключить мой первый impl
только для Arc
? Или есть лучший подход к проблеме?