Trait easy_cast::Conv

source ·
pub trait Conv<T>: Sized {
    fn try_conv(v: T) -> Result<Self>;

    fn conv(v: T) -> Self { ... }
}
Expand description

Like From, but supports fallible conversions

This trait is intented to be an extension over From, also supporting fallible conversions of numeric types. Since Rust does not yet have stable support for handling conflicting implementations (specialization or otherwise), only conversions between the most important numeric types are supported for now.

The sister-trait Cast supports “into” style usage.

Required Methods§

Try converting from T to Self

This method must fail on inexact conversions.

Provided Methods§

Convert from T to Self

This method must return the same result as Self::try_conv where that method succeeds, but differs in the handling of errors:

  • In debug builds the method panics on error
  • Otherwise, the method may panic or may return a different value, but like with the as keyword all results must be well-defined and safe.

Default implementations use Self::try_conv and panic on error. Implementations provided by this library will panic in debug builds or if the always_assert feature flag is used, and otherwise will behave identically to the as keyword.

This mirrors the behaviour of Rust’s overflow checks on integer arithmetic in that it is a tool for diagnosing logic errors where success is expected.

Examples found in repository?
src/traits.rs (line 87)
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    fn cast(self) -> T {
        T::conv(self)
    }
    #[inline]
    fn try_cast(self) -> Result<T> {
        T::try_conv(self)
    }
}

/// Like [`From`], but for approximate numerical conversions
///
/// On success, the result must be approximately the same as the input value:
/// the difference must be smaller than the precision of the target type.
/// For example, one may have `i32::conv_approx(1.9f32) = 1` or
/// `f32::conv_approx(1f64 + (f32::EPSILON as f64) / 2.0) = 1.0`.
///
/// Precise rounding mode should usually be truncation (round towards zero),
/// but this is not required. Use [`ConvFloat`] where a specific rounding mode
/// is required.
///
/// The sister-trait [`CastApprox`] supports "into" style usage.
pub trait ConvApprox<T>: Sized {
    /// Try converting from `T` to `Self`, allowing approximation of value
    ///
    /// This conversion may truncate excess precision not supported by the
    /// target type, so long as the *value* is approximately equal, from the
    /// point of view of precision of the target type.
    ///
    /// This method should allow approximate conversion, but fail on input not
    /// (approximately) in the target's range.
    fn try_conv_approx(x: T) -> Result<Self>;

    /// Converting from `T` to `Self`, allowing approximation of value
    ///
    /// This method must return the same result as [`Self::try_conv_approx`]
    /// where that method succeeds, but differs in the handling of errors:
    ///
    /// -   In debug builds the method panics on error
    /// -   Otherwise, the method may panic or may return a different value,
    ///     but like with the `as` keyword all results must be well-defined and
    ///     *safe*.
    ///
    /// Default implementations use [`Self::try_conv_approx`] and panic on error.
    /// Implementations provided by this library will panic in debug builds
    /// or if the `always_assert` feature flag is used, and otherwise will
    /// behave identically to the `as` keyword.
    ///
    /// This mirrors the behaviour of Rust's overflow checks on integer
    /// arithmetic in that it is a tool for diagnosing logic errors where
    /// success is expected.
    #[inline]
    fn conv_approx(x: T) -> Self {
        Self::try_conv_approx(x).unwrap_or_else(|e| {
            panic!("ConvApprox::conv_approx(_) failed: {}", e);
        })
    }
}

// TODO(specialization): implement also where T: ConvFloat<S>
impl<S, T: Conv<S>> ConvApprox<S> for T {
    #[inline]
    fn try_conv_approx(x: S) -> Result<Self> {
        T::try_conv(x)
    }
    #[inline]
    fn conv_approx(x: S) -> Self {
        T::conv(x)
    }
More examples
Hide additional examples
src/impl_basic.rs (line 55)
52
53
54
55
56
57
58
    fn conv(ss: [S; N]) -> Self {
        let mut tt = [T::default(); N];
        for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
            *t = T::conv(s);
        }
        tt
    }

Implementations on Foreign Types§

Implementors§