Skip to content

Commit 4c9495c

Browse files
committed
few api improvements:
- bump num-bigint to 0.3.0 - define Element ordering
1 parent 71c64c5 commit 4c9495c

File tree

4 files changed

+183
-35
lines changed

4 files changed

+183
-35
lines changed

foundationdb-bindingtester/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ foundationdb = { path = "../foundationdb", features = ["uuid", "num-bigint"] }
2525
foundationdb-sys = { version = "0.5.0", path = "../foundationdb-sys", default-features = false }
2626
futures = "0.3.0"
2727
log = "0.4.8"
28-
num-bigint = "0.2.6"
28+
num-bigint = "0.3.0"
2929
structopt = "0.3.3"

foundationdb/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ memchr = "2.2.1"
4545
rand = "0.7.2"
4646
static_assertions = "1.1.0"
4747
uuid = { version = "0.8.1", optional = true }
48-
num-bigint = { version = "0.2.6", optional = true }
48+
num-bigint = { version = "0.3.0", optional = true }
4949

5050
[dev-dependencies]
5151
byteorder = "1.3.2"

foundationdb/src/tuple/element.rs

Lines changed: 167 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,217 @@
1+
use super::pack::{f32_to_u32_be_bytes, f64_to_u64_be_bytes};
12
use super::{Bytes, Versionstamp};
2-
use std::borrow::Cow;
3+
use std::{borrow::Cow, cmp};
34

4-
#[derive(Clone, PartialEq, Debug)]
5+
#[cfg(feature = "num-bigint")]
6+
use std::convert::TryInto;
7+
8+
#[derive(Clone, Debug)]
59
pub enum Element<'a> {
610
Nil,
711
Bytes(Bytes<'a>),
812
String(Cow<'a, str>),
913
Tuple(Vec<Element<'a>>),
1014
Int(i64),
15+
#[cfg(feature = "num-bigint")]
16+
BigInt(num_bigint::BigInt),
1117
Float(f32),
1218
Double(f64),
1319
Bool(bool),
14-
Versionstamp(Versionstamp),
1520
#[cfg(feature = "uuid")]
1621
Uuid(uuid::Uuid),
17-
#[cfg(feature = "num-bigint")]
18-
BigInt(num_bigint::BigInt),
22+
Versionstamp(Versionstamp),
23+
}
24+
25+
struct CmpElement<'a, 'b>(&'a Element<'b>);
26+
27+
impl<'a, 'b> PartialEq for CmpElement<'a, 'b> {
28+
fn eq(&self, other: &Self) -> bool {
29+
self.cmp(other) == cmp::Ordering::Equal
30+
}
31+
}
32+
impl<'a, 'b> Eq for CmpElement<'a, 'b> {}
33+
34+
impl<'a, 'b> PartialOrd for CmpElement<'a, 'b> {
35+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
36+
Some(self.cmp(other))
37+
}
38+
}
39+
40+
impl<'a, 'b> Ord for CmpElement<'a, 'b> {
41+
fn cmp(&self, other: &Self) -> cmp::Ordering {
42+
self.0
43+
.code()
44+
.cmp(&other.0.code())
45+
.then_with(|| match (&self.0, &other.0) {
46+
(Element::Bytes(a), Element::Bytes(b)) => a.cmp(b),
47+
(Element::String(a), Element::String(b)) => a.cmp(b),
48+
(Element::Tuple(a), Element::Tuple(b)) => {
49+
let a_values = a.iter().map(CmpElement);
50+
let b_values = b.iter().map(CmpElement);
51+
a_values.cmp(b_values)
52+
}
53+
(Element::Int(a), Element::Int(b)) => a.cmp(b),
54+
#[cfg(feature = "num-bigint")]
55+
(Element::BigInt(a), Element::BigInt(b)) => a.cmp(b),
56+
(Element::Float(a), Element::Float(b)) => {
57+
f32_to_u32_be_bytes(*a).cmp(&f32_to_u32_be_bytes(*b))
58+
}
59+
(Element::Double(a), Element::Double(b)) => {
60+
f64_to_u64_be_bytes(*a).cmp(&f64_to_u64_be_bytes(*b))
61+
}
62+
#[cfg(feature = "uuid")]
63+
(Element::Uuid(a), Element::Uuid(b)) => a.cmp(b),
64+
(Element::Versionstamp(a), Element::Versionstamp(b)) => a.cmp(b),
65+
_ => cmp::Ordering::Equal,
66+
})
67+
}
68+
}
69+
70+
impl<'a> PartialEq for Element<'a> {
71+
fn eq(&self, other: &Self) -> bool {
72+
self.cmp(other) == cmp::Ordering::Equal
73+
}
74+
}
75+
impl<'a> Eq for Element<'a> {}
76+
77+
impl<'a> PartialOrd for Element<'a> {
78+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
79+
Some(self.cmp(other))
80+
}
81+
}
82+
impl<'a> Ord for Element<'a> {
83+
fn cmp(&self, other: &Self) -> cmp::Ordering {
84+
self.cmp_at_root(other)
85+
}
1986
}
2087

2188
impl<'a> Element<'a> {
89+
fn code(&self) -> u8 {
90+
match self {
91+
Element::Nil => super::NIL,
92+
Element::Bytes(_) => super::BYTES,
93+
Element::String(_) => super::STRING,
94+
Element::Tuple(_) => super::NESTED,
95+
Element::Int(_) => super::INTZERO,
96+
#[cfg(feature = "num-bigint")]
97+
Element::BigInt(_) => super::POSINTEND,
98+
Element::Float(_) => super::FLOAT,
99+
Element::Double(_) => super::DOUBLE,
100+
Element::Bool(v) => {
101+
if *v {
102+
super::TRUE
103+
} else {
104+
super::FALSE
105+
}
106+
}
107+
#[cfg(feature = "uuid")]
108+
Element::Uuid(_) => super::UUID,
109+
Element::Versionstamp(_) => super::VERSIONSTAMP,
110+
}
111+
}
112+
113+
#[inline]
114+
fn cmp_values(&self) -> &[Self] {
115+
match self {
116+
Element::Tuple(v) => v.as_slice(),
117+
v => std::slice::from_ref(v),
118+
}
119+
}
120+
121+
fn cmp_at_root<'b>(&self, b: &Element<'b>) -> cmp::Ordering {
122+
let a_values = self.cmp_values().iter().map(CmpElement);
123+
let b_values = b.cmp_values().iter().map(CmpElement);
124+
a_values.cmp(b_values)
125+
}
126+
22127
pub fn into_owned(self) -> Element<'static> {
23128
match self {
24129
Element::Nil => Element::Nil,
25-
Element::Bool(v) => Element::Bool(v),
130+
Element::Bytes(v) => Element::Bytes(v.into_owned().into()),
131+
Element::String(v) => Element::String(Cow::Owned(v.into_owned())),
132+
Element::Tuple(v) => Element::Tuple(v.into_iter().map(|e| e.into_owned()).collect()),
26133
Element::Int(v) => Element::Int(v),
134+
#[cfg(feature = "num-bigint")]
135+
Element::BigInt(v) => Element::BigInt(v),
27136
Element::Float(v) => Element::Float(v),
28137
Element::Double(v) => Element::Double(v),
29-
Element::String(v) => Element::String(Cow::Owned(v.into_owned())),
30-
Element::Bytes(v) => Element::Bytes(v.into_owned().into()),
31-
Element::Versionstamp(v) => Element::Versionstamp(v),
32-
Element::Tuple(v) => Element::Tuple(v.into_iter().map(|e| e.into_owned()).collect()),
138+
Element::Bool(v) => Element::Bool(v),
33139
#[cfg(feature = "uuid")]
34140
Element::Uuid(v) => Element::Uuid(v),
35-
#[cfg(feature = "num-bigint")]
36-
Element::BigInt(v) => Element::BigInt(v),
141+
Element::Versionstamp(v) => Element::Versionstamp(v),
37142
}
38143
}
39144

40-
pub fn as_bool(&self) -> Option<bool> {
41-
match *self {
42-
Element::Bool(v) => Some(v),
145+
pub fn as_bytes(&self) -> Option<&Bytes> {
146+
match self {
147+
Element::Bytes(v) => Some(v),
148+
_ => None,
149+
}
150+
}
151+
152+
pub fn as_str(&self) -> Option<&str> {
153+
match self {
154+
Element::String(v) => Some(&v),
155+
_ => None,
156+
}
157+
}
158+
159+
pub fn as_tuple(&self) -> Option<&[Element<'a>]> {
160+
match self {
161+
Element::Tuple(v) => Some(v.as_slice()),
43162
_ => None,
44163
}
45164
}
46165

47166
pub fn as_i64(&self) -> Option<i64> {
48-
match *self {
49-
Element::Int(v) => Some(v),
167+
match self {
168+
Element::Int(v) => Some(*v),
169+
#[cfg(feature = "num-bigint")]
170+
Element::BigInt(v) => v.try_into().ok(),
50171
_ => None,
51172
}
52173
}
53174

54-
pub fn as_str(&self) -> Option<&str> {
175+
#[cfg(feature = "num-bigint")]
176+
pub fn as_bigint(&self) -> Option<&num_bigint::BigInt> {
55177
match self {
56-
Element::String(v) => Some(&v),
178+
Element::BigInt(v) => Some(v),
57179
_ => None,
58180
}
59181
}
60182

61-
pub fn as_bytes(&self) -> Option<&Bytes> {
183+
pub fn as_f32(&self) -> Option<f32> {
62184
match self {
63-
Element::Bytes(v) => Some(v),
185+
Element::Float(v) => Some(*v),
64186
_ => None,
65187
}
66188
}
67189

68-
pub fn as_tuple(&self) -> Option<&[Element<'a>]> {
190+
pub fn as_f64(&self) -> Option<f64> {
69191
match self {
70-
Element::Tuple(v) => Some(v.as_slice()),
192+
Element::Double(v) => Some(*v),
193+
_ => None,
194+
}
195+
}
196+
197+
pub fn as_bool(&self) -> Option<bool> {
198+
match *self {
199+
Element::Bool(v) => Some(v),
200+
_ => None,
201+
}
202+
}
203+
204+
#[cfg(feature = "uuid")]
205+
pub fn as_uuid(&self) -> Option<&uuid::Uuid> {
206+
match self {
207+
Element::Uuid(v) => Some(v),
208+
_ => None,
209+
}
210+
}
211+
212+
pub fn as_versionstamp(&self) -> Option<&Versionstamp> {
213+
match self {
214+
Element::Versionstamp(v) => Some(v),
71215
_ => None,
72216
}
73217
}

foundationdb/src/tuple/pack.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -450,21 +450,25 @@ macro_rules! impl_ix {
450450
}
451451

452452
macro_rules! impl_fx {
453-
( $fx: ident, $parse_ux: ident, $ux: ident, $code: ident) => {
453+
( $fx: ident, $fx_to_ux_be_bytes: ident, $ux_width: tt, $parse_ux: ident, $ux: ident, $code: ident) => {
454+
#[inline]
455+
pub(super) fn $fx_to_ux_be_bytes(f: $fx) -> [u8; $ux_width] {
456+
let u = if f.is_sign_negative() {
457+
f.to_bits() ^ ::std::$ux::MAX
458+
} else {
459+
f.to_bits() ^ sign_bit!($ux)
460+
};
461+
u.to_be_bytes()
462+
}
454463
impl TuplePack for $fx {
455464
fn pack<W: io::Write>(
456465
&self,
457466
w: &mut W,
458467
_tuple_depth: TupleDepth,
459468
) -> io::Result<VersionstampOffset> {
460-
let f = *self;
461-
let u = if f.is_sign_negative() {
462-
f.to_bits() ^ ::std::$ux::MAX
463-
} else {
464-
f.to_bits() ^ sign_bit!($ux)
465-
};
469+
let bytes = $fx_to_ux_be_bytes(*self);
466470
w.write_all(&[$code])?;
467-
w.write_all(&u.to_be_bytes())?;
471+
w.write_all(&bytes)?;
468472
Ok(VersionstampOffset::None {
469473
size: std::mem::size_of::<$fx>() as u32 / 8 + 1,
470474
})
@@ -508,8 +512,8 @@ impl_ix!(i64, u64);
508512
impl_ix!(i128, u128, MAX_SZ);
509513
impl_ix!(isize, usize);
510514

511-
impl_fx!(f32, parse_u32, u32, FLOAT);
512-
impl_fx!(f64, parse_u64, u64, DOUBLE);
515+
impl_fx!(f32, f32_to_u32_be_bytes, 4, parse_u32, u32, FLOAT);
516+
impl_fx!(f64, f64_to_u64_be_bytes, 8, parse_u64, u64, DOUBLE);
513517

514518
#[cfg(feature = "num-bigint")]
515519
mod bigint {

0 commit comments

Comments
 (0)