File: lang_char.rs

package info (click to toggle)
rust-conv 0.3.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 336 kB
  • sloc: makefile: 2
file content (121 lines) | stat: -rw-r--r-- 3,426 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
extern crate conv;

#[macro_use] mod util;

use conv::*;

use conv::PosOverflow as Of;
use conv::Unrepresentable as Ur;

macro_rules! check {
    (@ $from:ty, $to:ty=> $(;)*) => {};

    (@ $from:ty, $to:ty=> try cident; $($tail:tt)*) => {
        check!(@ $from, $to=> try v: '\x00';);
        check!(@ $from, $to=> try v: '\x01';);
        check!(@ $from, $to=> $($tail)*);
    };

    (@ $from:ty, $to:ty=> try uident; $($tail:tt)*) => {
        check!(@ $from, $to=> try v: 0;);
        check!(@ $from, $to=> try v: 1;);
        check!(@ $from, $to=> $($tail)*);
    };

    (@ $from:ty, $to:ty=> try v: $src:expr, !$dst:expr; $($tail:tt)*) => {
        {
            let src: $from = $src;
            let dst: Result<$to, _> = src.try_into();
            assert_eq!(dst, Err($dst(src)));
        }
        check!(@ $from, $to=> $($tail)*);
    };

    (@ $from:ty, $to:ty=> try v: $src:expr; $($tail:tt)*) => {
        {
            let src: $from = $src;
            let dst: Result<$to, _> = src.try_into();
            assert_eq!(dst, Ok($src as $to));
        }
        check!(@ $from, $to=> $($tail)*);
    };

    (@ $from:ty, $to:ty=> qt: *; $($tail:tt)*) => {
        {
            extern crate quickcheck;

            fn property(v: $from) -> bool {
                let dst: Result<$to, _> = v.try_into();
                dst == Ok(v as $to)
            }

            let mut qc = quickcheck::QuickCheck::new();
            match qc.quicktest(property as fn($from) -> bool) {
                Ok(_) => (),
                Err(err) => panic!("qv {:?}", err)
            }
        }
        check!(@ $from, $to=> $($tail)*);
    };

    ($from:ty, $to:ty=> $($tail:tt)*) => {
        check! { @ $from, $to=> $($tail)*; }
    };
}

#[test]
fn test_i_to_c() {
    check!(u8, char => try uident; qt: *);

    /*
    `char` is a pain because `u8` is the *only* type you can cast directly from.  So, the `check!` macro is *basically useless*.

    Also, `char` has a great big hole in the middle, which makes things more interesting.

    Instead, we're just going to make sure that the conversions *exist* and have the expected error type.
    */
    macro_rules! check_i_to_c {
        ($($ts:ty),* $(,)*) => {
            $(
                {
                    let v: $ts = 0;
                    let r: Result<char, Ur<$ts>> = TryFrom::try_from(v);
                    assert_eq!(r, Ok('\x00'));
                }
            )*
        };
    }
    check_i_to_c!(i8, i16, i32, i64, isize, u16, u32, u64, usize);
}

#[test]
fn test_c_to_i() {
    check!(char, i8=> try cident;
        try v: '\u{80}', !Of;
    );
    check!(char, i16=> try cident;
        try v: '\u{8000}', !Of;
    );
    check!(char, i32=> try cident;);
    check!(char, i64=> try cident;);
    check!(char, u8=> try cident;
        try v: '\u{100}', !Of;
    );
    check!(char, u16=> try cident;
        try v: '\u{10000}', !Of;
    );
    check!(char, u32=> try cident;);
    check!(char, u64=> try cident;);
    for_bitness! {
        32 {
            check!(char, isize=> try cident;
                try v: '\u{10ffff}';
            );
            check!(char, usize=> try cident;);
        }
        64 {
            check!(char, i64=> try cident;);
            check!(char, u64=> try cident;);
        }
    }
}