每当
TryFrom
实现 T
时,我都会尝试为对象 T
实现 TryFrom
的通用实现。然而,我正在努力通过anyhow::Error
s。
在下面的代码中,我可以将
Generic<T>
转换为ValueContainer
,只要&usize: TryFrom<T>
即可。它几乎做了我想要的,但不允许我正确处理来自&usize: TryFrom<T>
的错误。
#[cfg(test)]
mod question {
use std::fmt::Debug;
use anyhow::anyhow;
#[derive(Debug)]
struct Generic<T: Debug>(T);
#[derive(Debug)]
struct Foo(usize);
#[derive(Debug)]
struct ValueContainer<'a>(&'a usize);
impl TryFrom<Foo> for &usize {
type Error = anyhow::Error;
fn try_from(value: Foo) -> Result<Self, Self::Error> {
if value.0 > 5 {
Ok(&5)
} else {
Err(anyhow!("Value must be bigger"))
}
}
}
impl<'a, T> TryFrom<Generic<T>> for ValueContainer<'a>
where
for<'b> &'b usize: TryFrom<T>,
T: Debug,
for<'b> anyhow::Error: From<<&'b usize as TryFrom<T>>::Error>,
{
type Error = anyhow::Error;
fn try_from(value: Generic<T>) -> Result<Self, Self::Error> {
// XXX: Can't do this?
// let value: &usize = value.0.try_into().unwrap();
match <&usize as TryFrom<T>>::try_from(value.0) {
Ok(v) => Ok(ValueContainer(v)),
Err(_) => {
// XXX: I would like this to be the error from the try_into above
// but there is an error `<&usize as TryFrom<T>>::Error` cannot be formatted with the default formatter`
return Err(anyhow!("Error converting type"));
}
}
}
}
#[test]
fn test_try_into() {
let value = Generic(Foo(10));
let value: Result<ValueContainer, anyhow::Error> = value.try_into();
dbg!(&value);
let value = Generic(Foo(2));
let value: Result<ValueContainer, anyhow::Error> = value.try_into();
dbg!(&value);
}
}
我无法在
value.try_into()?
的实现中使用 TryFrom<Generic<T>>
。取消注释 let value: &usize = value.try_into()?;
会产生错误
error[E0271]: type mismatch resolving `<&usize as TryFrom<Generic<T>>>::Error == <&usize as TryFrom<T>>::Error`
--> lib-doenetml-core/src/core/props/prop_view.rs:140:40
|
140 | let value: &usize = value.try_into()?;
| ^^^^^^^^ expected `Infallible`, found associated type
|
= note: expected enum `Infallible`
found associated type `<&usize as TryFrom<T>>::Error`
= help: consider constraining the associated type `<&usize as TryFrom<T>>::Error` to `Infallible`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
看起来 使用 TryInto 泛型无论如何::Error可能是相关的,它启发我添加
for<'b> anyhow::Error: From<<&'b usize as TryFrom<T>>::Error>
,但这似乎不起作用......
关于如何直接允许
value.try_into()?
有什么想法吗?
?
,
.0
将会起作用。
unwrap()
需要错误的 Debug
特征(因为它会在失败时打印它),因此您需要添加此绑定:
impl<'a, T> TryFrom<Generic<T>> for ValueContainer<'a>
where
for<'b> &'b usize: TryFrom<T>,
T: Debug,
for<'b> anyhow::Error: From<<&'b usize as TryFrom<T>>::Error>,
for<'b> <&'b usize as TryFrom<T>>::Error: Debug,
{
type Error = anyhow::Error;
fn try_from(value: Generic<T>) -> Result<Self, Self::Error> {
// XXX: Can't do this?
let value: &usize = value.0.try_into().unwrap();
Ok(ValueContainer(value))
}
}