Giter Site home page Giter Site logo

cast.rs's People

Contributors

apoelstra avatar bors[bot] avatar briansmith avatar eclipseo avatar emk avatar est31 avatar japaric avatar manishearth avatar sunfishcode avatar vitalyvb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cast.rs's Issues

Incorrect results/Undefined Behaviour for some float to int casts

Using 0.2.1 cast::u64(64f64.exp2()) returns Ok(0) when it should return Err(Overflow) just like cast::u32(32f64.exp2()) does.

The issue is

} else if src > $dst::MAX as $src {
where u64::MAX can't be stored exactly in a f64 so is rounded up to 264 causing the > to return false.

This applies to all float to int conversions where the number of bits in the destination type is larger than the number of bits in the source mantissa.

u8(255.0) yields Overflow

use cast::u8;

fn main() {
    println!("{:?}", u8(255.0)); // yields Overflow
}

It should be Ok(255), of course ๐Ÿ˜ƒ

Upgrading to quickcheck 1.0 causes some tests of floating point conversions to fail

See draft PR #38. All these tests fail regularly when quickcheck is upgraded to 1.0.3:

    test::demoting_to::i16::from::f32
    test::demoting_to::i16::from::f64
    test::demoting_to::i32::from::f32
    test::demoting_to::i32::from::f64
    test::demoting_to::i64::from::f32
    test::demoting_to::i64::from::f64
    test::demoting_to::i8::from::f32
    test::demoting_to::i8::from::f64
    test::demoting_to::isize::from::f32
    test::demoting_to::isize::from::f64
    test::demoting_to::u16::from::f32
    test::demoting_to::u16::from::f64
    test::demoting_to::u32::from::f32
    test::demoting_to::u32::from::f64
    test::demoting_to::u64::from::f32
    test::demoting_to::u64::from::f64
    test::demoting_to::u8::from::f32
    test::demoting_to::u8::from::f64
    test::demoting_to::usize::from::f32
    test::demoting_to::usize::from::f64

My initial guess is that the cause is the same bug as described in issue #23, and that quickcheck 1.0.3 provides coverage for the buggy cases.

Saturating casts

Most of the casts can only fail with overflow or underflow. Sometimes it would be nice to handle those casts using saturation instead of errors.

It would for instance be nice to have functions such as u8_saturate, with the property that u8_saturate(1234u16) = 255u8 and u8_saturate(-1u8) = 0u8.

Add CI to avoid errors on different platforms

This crate has quite a lot of conditionals, making it easy to miss updating some parts of the code. This is likely the cause of #29
Please consider adding CI, for example Github Actions to build and test on a range of supported systems, with 32-bit and 64-bit pointers etc.

u128/i128

Please stabilize this feature or at least provide an cfg entry for using it in recent compiler versions

u128/i128 support

Needed by tests for rust-lang/compiler-builtins#161 .

I would like to have an implementation of the trait tests::cast::From<i128> for f32, and similar implementations needed to test i128/u128 <-> float conversion functions

`cast::Error` does not implement `Error` trait

Hello! I'm using the cast library in some production code, and it's great! I like the way that casts only return Result if they might fail.

I'm also using the error-chain crate, which provides support for converting many different error types into my library's "official" error type. But for this to work, all error types need to implement the Display and Error traits. Would you be interested in a pull request adding support for this to your cast library?

Thank you for considering this!

Make it possible to avoid the `rustc_version` and `semver` build dependencies

Hi, I'd like to use cast.rs but I'd also like to minimize my dependency tree. I noticed that rustc_version seems to be used primarily to decide whether to support 128-bit types. But, 128-bit types have been in stable Rust for years. I think it would be a better trade-off to break compatibility with the ancient versions of Rust with a new version that eliminates this conditional check. I would be happy to submit a PR that does this if you agree this makes sense.

cast 0.2.4 fails on `i686-unknown-linux-gnu`

Compiling cast 0.2.4 on i686-unknown-linux-gnu target fails to compile. 0.2.3 works fine.
Log:

error[E0432]: unresolved import `Error`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:361:10
    |
361 |     use {Error, From};
    |          ^^^^^ no external crate `Error`

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:192:21
    |
192 |                       type Output = $dst;
    |                       ^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
364 | /     promotion! {
365 | |         i8    => f32, f64, i8, i16, i32, isize, i64;
366 | |         i16   => f32, f64,     i16, i32, isize, i64;
367 | |         i32   => f32, f64,          i32, isize, i64;
368 | |         isize => f32, f64,          i32, isize, i64;
369 | |         i64   => f32, f64,                      i64;
370 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:195:21
    |
195 | /                     fn cast(src: $src) -> $dst {
196 | |                         src as $dst
197 | |                     }
    | |_____________________^ not a member of trait `From`
...
364 | /     promotion! {
365 | |         i8    => f32, f64, i8, i16, i32, isize, i64;
366 | |         i16   => f32, f64,     i16, i32, isize, i64;
367 | |         i32   => f32, f64,          i32, isize, i64;
368 | |         isize => f32, f64,          i32, isize, i64;
369 | |         i64   => f32, f64,                      i64;
370 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:210:21
    |
210 |                       type Output = Result<$dst, Error>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
372 | /     half_promotion! {
373 | |         i8    =>                                     u8, u16, u32, usize, u64;
374 | |         i16   =>                                         u16, u32, usize, u64;
375 | |         i32   =>                                              u32, usize, u64;
376 | |         isize =>                                              u32, usize, u64;
377 | |         i64   =>                                                          u64;
378 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:213:21
    |
213 | /                     fn cast(src: $src) -> Self::Output {
214 | |                         if src < 0 {
215 | |                             Err(Error::Underflow)
216 | |                         } else {
217 | |                             Ok(src as $dst)
218 | |                         }
219 | |                     }
    | |_____________________^ not a member of trait `From`
...
372 | /     half_promotion! {
373 | |         i8    =>                                     u8, u16, u32, usize, u64;
374 | |         i16   =>                                         u16, u32, usize, u64;
375 | |         i32   =>                                              u32, usize, u64;
376 | |         isize =>                                              u32, usize, u64;
377 | |         i64   =>                                                          u64;
378 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:256:21
    |
256 |                       type Output = Result<$dst, Error>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
380 | /     from_signed! {
381 | |
382 | |         i16   =>           i8,                       u8;
383 | |         i32   =>           i8, i16,                  u8, u16;
384 | |         isize =>           i8, i16,                  u8, u16;
385 | |         i64   =>           i8, i16, i32, isize,      u8, u16, u32, usize;
386 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:259:21
    |
259 | /                     fn cast(src: $src) -> Self::Output {
260 | |                         use core::$dst;
261 | |
262 | |                         Err(if src < $dst::MIN as $src {
...   |
268 | |                         })
269 | |                     }
    | |_____________________^ not a member of trait `From`
...
380 | /     from_signed! {
381 | |
382 | |         i16   =>           i8,                       u8;
383 | |         i32   =>           i8, i16,                  u8, u16;
384 | |         isize =>           i8, i16,                  u8, u16;
385 | |         i64   =>           i8, i16, i32, isize,      u8, u16, u32, usize;
386 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:192:21
    |
192 |                       type Output = $dst;
    |                       ^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
389 | /     promotion! {
390 | |         u8    => f32, f64,     i16, i32, isize, i64, u8, u16, u32, usize, u64;
391 | |         u16   => f32, f64,          i32, isize, i64,     u16, u32, usize, u64;
392 | |         u32   => f32, f64,                      i64,          u32, usize, u64;
393 | |         usize => f32, f64,                      i64,          u32, usize, u64;
394 | |         u64   => f32, f64,                                                u64;
395 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:195:21
    |
195 | /                     fn cast(src: $src) -> $dst {
196 | |                         src as $dst
197 | |                     }
    | |_____________________^ not a member of trait `From`
...
389 | /     promotion! {
390 | |         u8    => f32, f64,     i16, i32, isize, i64, u8, u16, u32, usize, u64;
391 | |         u16   => f32, f64,          i32, isize, i64,     u16, u32, usize, u64;
392 | |         u32   => f32, f64,                      i64,          u32, usize, u64;
393 | |         usize => f32, f64,                      i64,          u32, usize, u64;
394 | |         u64   => f32, f64,                                                u64;
395 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:232:21
    |
232 |                       type Output = Result<$dst, Error>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
397 | /     from_unsigned! {
398 | |         u8    =>           i8;
399 | |         u16   =>           i8, i16,                  u8;
400 | |         u32   =>           i8, i16, i32, isize,      u8, u16;
401 | |         usize =>           i8, i16, i32, isize,      u8, u16;
402 | |         u64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize;
403 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:235:21
    |
235 | /                     fn cast(src: $src) -> Self::Output {
236 | |                         use core::$dst;
237 | |
238 | |                         if src > $dst::MAX as $src {
...   |
242 | |                         }
243 | |                     }
    | |_____________________^ not a member of trait `From`
...
397 | /     from_unsigned! {
398 | |         u8    =>           i8;
399 | |         u16   =>           i8, i16,                  u8;
400 | |         u32   =>           i8, i16, i32, isize,      u8, u16;
401 | |         usize =>           i8, i16, i32, isize,      u8, u16;
402 | |         u64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize;
403 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:192:21
    |
192 |                       type Output = $dst;
    |                       ^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
406 | /     promotion! {
407 | |         f32   => f32, f64;
408 | |         f64   =>      f64;
409 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:195:21
    |
195 | /                     fn cast(src: $src) -> $dst {
196 | |                         src as $dst
197 | |                     }
    | |_____________________^ not a member of trait `From`
...
406 | /     promotion! {
407 | |         f32   => f32, f64;
408 | |         f64   =>      f64;
409 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0437]: type `Output` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:282:21
    |
282 |                       type Output = Result<$dst, Error>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `From`
...
411 | /     from_float! {
412 | |         f32, u32 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
413 | |         f64, u64 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
414 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `cast` is not a member of trait `From`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:285:21
    |
285 | /                     fn cast(src: $src) -> Self::Output {
286 | |                         use core::{$dst, $src};
287 | |
288 | |                         Err(if src != src {
...   |
317 | |                         })
318 | |                     }
    | |_____________________^ not a member of trait `From`
...
411 | /     from_float! {
412 | |         f32, u32 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
413 | |         f64, u64 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
414 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0220]: associated type `Output` not found for `Self`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:213:49
    |
213 |                       fn cast(src: $src) -> Self::Output {
    |                                                   ^^^^^^ associated type `Output` not found
...
372 | /     half_promotion! {
373 | |         i8    =>                                     u8, u16, u32, usize, u64;
374 | |         i16   =>                                         u16, u32, usize, u64;
375 | |         i32   =>                                              u32, usize, u64;
376 | |         isize =>                                              u32, usize, u64;
377 | |         i64   =>                                                          u64;
378 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0220]: associated type `Output` not found for `Self`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:259:49
    |
259 |                       fn cast(src: $src) -> Self::Output {
    |                                                   ^^^^^^ associated type `Output` not found
...
380 | /     from_signed! {
381 | |
382 | |         i16   =>           i8,                       u8;
383 | |         i32   =>           i8, i16,                  u8, u16;
384 | |         isize =>           i8, i16,                  u8, u16;
385 | |         i64   =>           i8, i16, i32, isize,      u8, u16, u32, usize;
386 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0220]: associated type `Output` not found for `Self`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:235:49
    |
235 |                       fn cast(src: $src) -> Self::Output {
    |                                                   ^^^^^^ associated type `Output` not found
...
397 | /     from_unsigned! {
398 | |         u8    =>           i8;
399 | |         u16   =>           i8, i16,                  u8;
400 | |         u32   =>           i8, i16, i32, isize,      u8, u16;
401 | |         usize =>           i8, i16, i32, isize,      u8, u16;
402 | |         u64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize;
403 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0220]: associated type `Output` not found for `Self`
   --> /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/cast-0.2.4/src/lib.rs:285:49
    |
285 |                       fn cast(src: $src) -> Self::Output {
    |                                                   ^^^^^^ associated type `Output` not found
...
411 | /     from_float! {
412 | |         f32, u32 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
413 | |         f64, u64 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
414 | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

Code supporting both 32-bit and 64-bit platforms

The following code compiles on 64-bit targets:

fn main() {
    let a: usize = 2;
    let b: u32 = cast::u32(a).unwrap();
    let c: u64 = cast::u64(a);
    let _d: usize = cast::usize(b);
    let _e: usize = cast::usize(c);
}

However, it doesn't compile on a 32-bit target:

error[E0599]: no method named `unwrap` found for type `u32` in the current scope
 --> src/main.rs:3:31
  |
3 |     let b: u32 = cast::u32(a).unwrap();
  |                               ^^^^^^

error[E0308]: mismatched types
 --> src/main.rs:6:21
  |
6 |     let _e: usize = cast::usize(c);
  |                     ^^^^^^^^^^^^^^ expected usize, found enum `std::result::Result`
  |
  = note: expected type `usize`
             found type `std::result::Result<usize, cast::Error>`

because the Output types use Result or not depending on the target's usize size.

Is there a way to write code that does checked (when needed) casts between fixed-sized types and usize that works on both 32-bit and 64-bit platforms?

I might be looking for something returning a Result on both, relying on inlining and optimization to eliminate the overhead in cases where the conversion turns out to be trivial.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.