compact_str/repr/
traits.rs1use core::hint::unreachable_unchecked;
2
3use super::Repr;
4use crate::ToCompactStringError;
5
6const FALSE: Repr = Repr::const_new("false");
7const TRUE: Repr = Repr::const_new("true");
8
9pub(crate) trait IntoRepr {
11 fn into_repr(self) -> Result<Repr, ToCompactStringError>;
12}
13
14impl IntoRepr for f32 {
15 #[inline]
16 fn into_repr(self) -> Result<Repr, ToCompactStringError> {
17 let mut buf = ryu::Buffer::new();
18 let s = buf.format(self);
19 Ok(Repr::new(s)?)
20 }
21}
22
23impl IntoRepr for f64 {
24 #[inline]
25 fn into_repr(self) -> Result<Repr, ToCompactStringError> {
26 let mut buf = ryu::Buffer::new();
27 let s = buf.format(self);
28 Ok(Repr::new(s)?)
29 }
30}
31
32impl IntoRepr for bool {
33 #[inline]
34 fn into_repr(self) -> Result<Repr, ToCompactStringError> {
35 if self {
36 Ok(TRUE)
37 } else {
38 Ok(FALSE)
39 }
40 }
41}
42
43impl IntoRepr for char {
44 #[inline]
45 fn into_repr(self) -> Result<Repr, ToCompactStringError> {
46 let mut buf = [0_u8; 4];
47 let s = self.encode_utf8(&mut buf);
48
49 match s.len() {
51 1..=4 => (),
52 _ => unsafe { unreachable_unchecked() },
54 }
55
56 Ok(Repr::new(s)?)
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use alloc::string::ToString;
63
64 use quickcheck_macros::quickcheck;
65
66 use super::IntoRepr;
67
68 #[test]
69 fn test_into_repr_bool() {
70 let t = true;
71 let repr = t.into_repr().unwrap();
72 assert_eq!(repr.as_str(), t.to_string());
73
74 let f = false;
75 let repr = f.into_repr().unwrap();
76 assert_eq!(repr.as_str(), f.to_string());
77 }
78
79 #[quickcheck]
80 #[cfg_attr(miri, ignore)]
81 fn quickcheck_into_repr_char(val: char) {
82 let repr = char::into_repr(val).unwrap();
83 assert_eq!(repr.as_str(), val.to_string());
84 }
85
86 #[test]
87 fn test_into_repr_f64_sanity() {
88 let vals = [
89 f64::MIN,
90 f64::MIN_POSITIVE,
91 f64::MAX,
92 f64::NEG_INFINITY,
93 f64::INFINITY,
94 ];
95
96 for x in &vals {
97 let repr = f64::into_repr(*x).unwrap();
98 let roundtrip = repr.as_str().parse::<f64>().unwrap();
99
100 assert_eq!(*x, roundtrip);
101 }
102 }
103
104 #[test]
105 fn test_into_repr_f64_nan() {
106 let repr = f64::into_repr(f64::NAN).unwrap();
107 let roundtrip = repr.as_str().parse::<f64>().unwrap();
108 assert!(roundtrip.is_nan());
109 }
110
111 #[quickcheck]
112 #[cfg_attr(miri, ignore)]
113 fn quickcheck_into_repr_f64(val: f64) {
114 let repr = f64::into_repr(val).unwrap();
115 let roundtrip = repr.as_str().parse::<f64>().unwrap();
116
117 if val.is_nan() != roundtrip.is_nan() {
121 assert_eq!(val, roundtrip);
122 }
123 }
124
125 #[test]
129 #[cfg_attr(all(target_arch = "powerpc64", target_pointer_width = "64"), ignore)]
130 fn test_into_repr_f32_sanity() {
131 let vals = [
132 f32::MIN,
133 f32::MIN_POSITIVE,
134 f32::MAX,
135 f32::NEG_INFINITY,
136 f32::INFINITY,
137 ];
138
139 for x in &vals {
140 let repr = f32::into_repr(*x).unwrap();
141 let roundtrip = repr.as_str().parse::<f32>().unwrap();
142
143 assert_eq!(*x, roundtrip);
144 }
145 }
146
147 #[test]
148 #[cfg_attr(all(target_arch = "powerpc64", target_pointer_width = "64"), ignore)]
149 fn test_into_repr_f32_nan() {
150 let repr = f32::into_repr(f32::NAN).unwrap();
151 let roundtrip = repr.as_str().parse::<f32>().unwrap();
152 assert!(roundtrip.is_nan());
153 }
154
155 #[quickcheck]
156 #[cfg_attr(all(target_arch = "powerpc64", target_pointer_width = "64"), ignore)]
157 fn proptest_into_repr_f32(val: f32) {
158 let repr = f32::into_repr(val).unwrap();
159 let roundtrip = repr.as_str().parse::<f32>().unwrap();
160
161 if val.is_nan() != roundtrip.is_nan() {
165 assert_eq!(val, roundtrip);
166 }
167 }
168}