7 个版本
使用旧的 Rust 2015
0.3.3 | 2016 年 3 月 30 日 |
---|---|
0.3.2 | 2016 年 3 月 14 日 |
0.3.1 | 2015 年 11 月 30 日 |
0.3.0 | 2015 年 10 月 13 日 |
0.1.0 | 2015 年 8 月 7 日 |
#801 in Rust 模式
122,124 下载/月
用于 313 个软件包 (57 个直接)
77KB
1K SLoC
conv
此软件包提供了一些转换特性,其语义比 as
或 From
/Into
提供的更具体。
提供这些特性的目标是要更具体地说明泛型代码可以依赖的内容,以及提供对标准 From
/Into
特性的合理自我描述替代方案。例如,虽然 T: From<U>
在泛型代码中可能成立,但这并没有说明这种转换代表了什么 类型 的转换。
此外,From
/Into
并没有提供转换失败的功能,这意味着实现者可能需要在可能不合法的转换或崩溃之间进行选择;这两种选择在一般情况下都不吸引人。
链接
兼容性
conv
与 Rust 1.2 及更高版本兼容。
示例
# extern crate conv;
# use conv::*;
# fn main() {
// This *cannot* fail, so we can use `unwrap_ok` to discard the `Result`.
assert_eq!(u8::value_from(0u8).unwrap_ok(), 0u8);
// This *can* fail. Specifically, it can overflow toward negative infinity.
assert_eq!(u8::value_from(0i8), Ok(0u8));
assert_eq!(u8::value_from(-1i8), Err(NegOverflow(-1)));
// This can overflow in *either* direction; hence the change to `RangeError`.
assert_eq!(u8::value_from(-1i16), Err(RangeError::NegOverflow(-1)));
assert_eq!(u8::value_from(0i16), Ok(0u8));
assert_eq!(u8::value_from(256i16), Err(RangeError::PosOverflow(256)));
// We can use the extension traits to simplify this a little.
assert_eq!(u8::value_from(-1i16).unwrap_or_saturate(), 0u8);
assert_eq!(u8::value_from(0i16).unwrap_or_saturate(), 0u8);
assert_eq!(u8::value_from(256i16).unwrap_or_saturate(), 255u8);
// Obviously, all integers can be "approximated" using the default scheme (it
// doesn't *do* anything), but they can *also* be approximated with the
// `Wrapping` scheme.
assert_eq!(
<u8 as ApproxFrom<_, DefaultApprox>>::approx_from(400u16),
Err(PosOverflow(400)));
assert_eq!(
<u8 as ApproxFrom<_, Wrapping>>::approx_from(400u16),
Ok(144u8));
// This is rather inconvenient; as such, there are a number of convenience
// extension methods available via `ConvUtil` and `ConvAsUtil`.
assert_eq!(400u16.approx(), Err::<u8, _>(PosOverflow(400)));
assert_eq!(400u16.approx_by::<Wrapping>(), Ok::<u8, _>(144u8));
assert_eq!(400u16.approx_as::<u8>(), Err(PosOverflow(400)));
assert_eq!(400u16.approx_as_by::<u8, Wrapping>(), Ok(144));
// Integer -> float conversions *can* fail due to limited precision.
// Once the continuous range of exactly representable integers is exceeded, the
// provided implementations fail with overflow errors.
assert_eq!(f32::value_from(16_777_216i32), Ok(16_777_216.0f32));
assert_eq!(f32::value_from(16_777_217i32), Err(RangeError::PosOverflow(16_777_217)));
// Float -> integer conversions have to be done using approximations. Although
// exact conversions are *possible*, "advertising" this with an implementation
// is misleading.
//
// Note that `DefaultApprox` for float -> integer uses whatever rounding
// mode is currently active (*i.e.* whatever `as` would do).
assert_eq!(41.0f32.approx(), Ok(41u8));
assert_eq!(41.3f32.approx(), Ok(41u8));
assert_eq!(41.5f32.approx(), Ok(41u8));
assert_eq!(41.8f32.approx(), Ok(41u8));
assert_eq!(42.0f32.approx(), Ok(42u8));
assert_eq!(255.0f32.approx(), Ok(255u8));
assert_eq!(256.0f32.approx(), Err::<u8, _>(FloatError::PosOverflow(256.0)));
// Sometimes, it can be useful to saturate the conversion from float to
// integer directly, then account for NaN as input separately. The `Saturate`
// extension trait exists for this reason.
assert_eq!((-23.0f32).approx_as::<u8>().saturate(), Ok(0));
assert_eq!(302.0f32.approx_as::<u8>().saturate(), Ok(255u8));
assert!(std::f32::NAN.approx_as::<u8>().saturate().is_err());
// If you really don't care about the specific kind of error, you can just rely
// on automatic conversion to `GeneralErrorKind`.
fn too_many_errors() -> Result<(), GeneralErrorKind> {
assert_eq!({let r: u8 = try!(0u8.value_into()); r}, 0u8);
assert_eq!({let r: u8 = try!(0i8.value_into()); r}, 0u8);
assert_eq!({let r: u8 = try!(0i16.value_into()); r}, 0u8);
assert_eq!({let r: u8 = try!(0.0f32.approx()); r}, 0u8);
Ok(())
}
# let _ = too_many_errors();
# }
变更日志
v0.3.2
- 添加了整数 ↔
char
转换。 - 添加了缺失的
isize
/usize
→f32
/f64
转换。 - 修复了 64 位目标上
i64
→usize
的错误类型。
v0.3.1
- 将
unwrap_ok
修改为更好的代码生成(感谢 bluss)。 - 修复 Rust 破坏性变更(有问题的代码本身也不太对;感谢 m4rw3r)。
v0.3.0
- 为所有
Err
关联类型添加了Error
约束。这将破坏任何用户定义的转换,其中Err
类型没有实现Error
。 - 已将
Overflow
和Underflow
错误分别重命名为PosOverflow
和NegOverflow
。在浮点数转换的上下文中,“下溢”通常意味着值太接近零,无法正确表示。
v0.2.1
- 添加了
ConvUtil::into_as<Dst>
作为Into::<Dst>::into
的快捷方式。 - 添加了
#[inline]
属性。 - 添加了
Saturate::saturate
,它可以饱和来自溢出/下溢的Result
。
v0.2.0
- 将所有错误类型更改为包含原始输入作为有效负载。这几乎破坏了所有东西。对此表示歉意。从积极的一面来看,现在使用非
Copy
类型的转换特性没有任何缺点。 - 添加了浮点数到整数的近似值的标准舍入模式:
RoundToNearest
、RoundToNegInf
、RoundToPosInf
和RoundToZero
。 ApproxWith
现在包含在一个扩展特性对 (ConvUtil
和ConvAsUtil
) 中,它还有TryInto
和ValueInto
的快捷方式,这样您就可以在方法中指定目标类型。