1#![allow(clippy::len_without_is_empty)]
2
3use std::ops::Deref;
4
5pub use byteorder::LittleEndian as Endianness;
6
7mod bitset;
8pub mod file_slice;
9mod group_by;
10mod serialize;
11mod vint;
12mod writer;
13pub use bitset::*;
14pub use group_by::GroupByIteratorExtended;
15pub use ownedbytes::{OwnedBytes, StableDeref};
16pub use serialize::{BinarySerializable, DeserializeFrom, FixedSize};
17pub use vint::{
18 deserialize_vint_u128, read_u32_vint, read_u32_vint_no_advance, serialize_vint_u128,
19 serialize_vint_u32, write_u32_vint, VInt, VIntU128,
20};
21pub use writer::{AntiCallToken, CountingWriter, TerminatingWrite};
22
23pub trait HasLen {
25 fn len(&self) -> usize;
27
28 fn is_empty(&self) -> bool {
30 self.len() == 0
31 }
32}
33
34impl<T: Deref<Target = [u8]>> HasLen for T {
35 fn len(&self) -> usize {
36 self.deref().len()
37 }
38}
39
40const HIGHEST_BIT: u64 = 1 << 63;
41
42#[inline]
63pub fn i64_to_u64(val: i64) -> u64 {
64 (val as u64) ^ HIGHEST_BIT
65}
66
67#[inline]
69pub fn u64_to_i64(val: u64) -> i64 {
70 (val ^ HIGHEST_BIT) as i64
71}
72
73#[inline]
91pub fn f64_to_u64(val: f64) -> u64 {
92 let bits = val.to_bits();
93 if val.is_sign_positive() {
94 bits ^ HIGHEST_BIT
95 } else {
96 !bits
97 }
98}
99
100#[inline]
102pub fn u64_to_f64(val: u64) -> f64 {
103 f64::from_bits(if val & HIGHEST_BIT != 0 {
104 val ^ HIGHEST_BIT
105 } else {
106 !val
107 })
108}
109
110#[cfg(test)]
111pub mod test {
112
113 use proptest::prelude::*;
114
115 use super::{f64_to_u64, i64_to_u64, u64_to_f64, u64_to_i64, BinarySerializable, FixedSize};
116
117 fn test_i64_converter_helper(val: i64) {
118 assert_eq!(u64_to_i64(i64_to_u64(val)), val);
119 }
120
121 fn test_f64_converter_helper(val: f64) {
122 assert_eq!(u64_to_f64(f64_to_u64(val)), val);
123 }
124
125 pub fn fixed_size_test<O: BinarySerializable + FixedSize + Default>() {
126 let mut buffer = Vec::new();
127 O::default().serialize(&mut buffer).unwrap();
128 assert_eq!(buffer.len(), O::SIZE_IN_BYTES);
129 }
130
131 proptest! {
132 #[test]
133 fn test_f64_converter_monotonicity_proptest((left, right) in (proptest::num::f64::NORMAL, proptest::num::f64::NORMAL)) {
134 let left_u64 = f64_to_u64(left);
135 let right_u64 = f64_to_u64(right);
136 assert_eq!(left_u64 < right_u64, left < right);
137 }
138 }
139
140 #[test]
141 fn test_i64_converter() {
142 assert_eq!(i64_to_u64(i64::MIN), u64::MIN);
143 assert_eq!(i64_to_u64(i64::MAX), u64::MAX);
144 test_i64_converter_helper(0i64);
145 test_i64_converter_helper(i64::MIN);
146 test_i64_converter_helper(i64::MAX);
147 for i in -1000i64..1000i64 {
148 test_i64_converter_helper(i);
149 }
150 }
151
152 #[test]
153 fn test_f64_converter() {
154 test_f64_converter_helper(f64::INFINITY);
155 test_f64_converter_helper(f64::NEG_INFINITY);
156 test_f64_converter_helper(0.0);
157 test_f64_converter_helper(-0.0);
158 test_f64_converter_helper(1.0);
159 test_f64_converter_helper(-1.0);
160 }
161
162 #[test]
163 fn test_f64_order() {
164 assert!(!(f64_to_u64(f64::NEG_INFINITY)..f64_to_u64(f64::INFINITY))
165 .contains(&f64_to_u64(f64::NAN))); assert!(f64_to_u64(1.5) > f64_to_u64(1.0)); assert!(f64_to_u64(2.0) > f64_to_u64(1.0)); assert!(f64_to_u64(2.0) > f64_to_u64(1.5)); assert!(f64_to_u64(1.0) > f64_to_u64(-1.0)); assert!(f64_to_u64(-1.5) < f64_to_u64(-1.0));
171 assert!(f64_to_u64(-2.0) < f64_to_u64(1.0));
172 assert!(f64_to_u64(-2.0) < f64_to_u64(-1.5));
173 }
174}