Skip to content

Commit 4b86ae5

Browse files
rushmorembluejekyll
authored andcommitted
split Single and Tuple traits into Encode and Decode
Fixes #53
1 parent 0ed2561 commit 4b86ae5

File tree

5 files changed

+150
-113
lines changed

5 files changed

+150
-113
lines changed

foundationdb/src/bin/bindingtester.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::collections::HashMap;
99
use fdb::error::FdbError;
1010
use fdb::keyselector::KeySelector;
1111
use fdb::tuple::*;
12-
use fdb::tuple::single::*;
1312
use fdb::*;
1413
use futures::future::*;
1514
use futures::prelude::*;
@@ -177,7 +176,7 @@ impl Instr {
177176
fn from(data: &[u8]) -> Self {
178177
use InstrCode::*;
179178

180-
let tup: tuple::Value = Tuple::decode(data).unwrap();
179+
let tup: tuple::Value = tuple::Decode::decode(data).unwrap();
181180
let cmd = match tup.0[0] {
182181
single::Value::Str(ref s) => s.clone(),
183182
_ => panic!("unexpected instr"),
@@ -192,7 +191,7 @@ impl Instr {
192191

193192
let code = match cmd {
194193
"PUSH" => {
195-
let data = Single::encode_to_vec(&tup.0[1]);
194+
let data = single::Encode::encode_to_vec(&tup.0[1]);
196195
Push(data)
197196
}
198197
"DUP" => Dup,
@@ -281,13 +280,13 @@ impl StackItem {
281280

282281
//TODO: wait
283282
match self.fut.unwrap().wait() {
284-
Ok((_trx, data)) => Single::encode_to_vec(&data),
283+
Ok((_trx, data)) => single::Encode::encode_to_vec(&data),
285284
Err(e) => {
286285
let code = format!("{}", e.code());
287286
let tup = (b"ERROR".to_vec(), code.into_bytes());
288287
debug!("ERROR: {:?}", e);
289-
let bytes = Tuple::encode_to_vec(&tup);
290-
Single::encode_to_vec(&bytes)
288+
let bytes = tuple::Encode::encode_to_vec(&tup);
289+
single::Encode::encode_to_vec(&bytes)
291290
}
292291
}
293292
}
@@ -380,10 +379,10 @@ impl StackMachine {
380379

381380
fn pop_single<S>(&mut self) -> S
382381
where
383-
S: Single,
382+
S: single::Decode,
384383
{
385384
let data = self.pop().data();
386-
match Single::decode_full(&data) {
385+
match single::Decode::decode_full(&data) {
387386
Ok(v) => v,
388387
Err(e) => {
389388
panic!("failed to decode single {:?}: {:?}", data, e);
@@ -405,9 +404,9 @@ impl StackMachine {
405404

406405
fn push_single<S>(&mut self, number: usize, s: &S)
407406
where
408-
S: Single,
407+
S: single::Encode,
409408
{
410-
let data = Single::encode_to_vec(s);
409+
let data = single::Encode::encode_to_vec(s);
411410
self.push(number, data);
412411
}
413412

@@ -601,8 +600,8 @@ impl StackMachine {
601600
continue;
602601
}
603602
}
604-
Single::encode(&key.to_vec(), &mut out).expect("failed to encode");
605-
Single::encode(&value.to_vec(), &mut out).expect("failed to encode");
603+
single::Encode::encode(&key.to_vec(), &mut out).expect("failed to encode");
604+
single::Encode::encode(&value.to_vec(), &mut out).expect("failed to encode");
606605
}
607606
Ok(out)
608607
})
@@ -723,8 +722,8 @@ impl StackMachine {
723722
let mut data = data.as_slice();
724723

725724
while !data.is_empty() {
726-
let (val, offset): (single::Value, _) = Single::decode(data).unwrap();
727-
let bytes = Single::encode_to_vec(&val);
725+
let (val, offset): (single::Value, _) = single::Decode::decode(data).unwrap();
726+
let bytes = single::Encode::encode_to_vec(&val);
728727
self.push_single(number, &bytes);
729728
data = &data[offset..];
730729
}

foundationdb/src/subspace.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//! general guidance on subspace usage, see the Subspaces section of the Developer Guide
1616
//! (https://apple.github.io/foundationdb/developer-guide.html#subspaces).
1717
18-
use tuple::{self, Tuple};
18+
use tuple::{self, Encode, Decode};
1919

2020
/// Subspace represents a well-defined region of keyspace in a FoundationDB database.
2121
#[derive(Debug, Clone)]
@@ -36,14 +36,14 @@ impl Subspace {
3636
}
3737
}
3838

39-
/// `from_bytes` returns a new Subspace from the provided Tuple.
40-
pub fn new<T: Tuple>(t: &T) -> Self {
41-
let prefix = Tuple::encode_to_vec(t);
39+
/// Returns a new Subspace from the provided tuple encodable.
40+
pub fn new<T: Encode>(t: &T) -> Self {
41+
let prefix = Encode::encode_to_vec(t);
4242
Self { prefix }
4343
}
4444

45-
/// `subspace` returns a new Subspace whose prefix extends this Subspace with a given tuple.
46-
pub fn subspace<T: Tuple>(&self, t: &T) -> Self {
45+
/// Returns a new Subspace whose prefix extends this Subspace with a given tuple encodable.
46+
pub fn subspace<T: Encode>(&self, t: &T) -> Self {
4747
Self {
4848
prefix: self.pack(t),
4949
}
@@ -54,10 +54,10 @@ impl Subspace {
5454
self.prefix.as_slice()
5555
}
5656

57-
/// `pack` returns the key encoding the specified Tuple with the prefix of this Subspace
57+
/// Returns the key encoding the specified Tuple with the prefix of this Subspace
5858
/// prepended.
59-
pub fn pack<T: Tuple>(&self, t: &T) -> Vec<u8> {
60-
let mut packed = Tuple::encode_to_vec(t);
59+
pub fn pack<T: Encode>(&self, t: &T) -> Vec<u8> {
60+
let mut packed = Encode::encode_to_vec(t);
6161
let mut out = Vec::with_capacity(self.prefix.len() + packed.len());
6262
out.extend_from_slice(&self.prefix);
6363
out.append(&mut packed);
@@ -67,12 +67,12 @@ impl Subspace {
6767
/// `unpack` returns the Tuple encoded by the given key with the prefix of this Subspace
6868
/// removed. `unpack` will return an error if the key is not in this Subspace or does not
6969
/// encode a well-formed Tuple.
70-
pub fn unpack<T: Tuple>(&self, key: &[u8]) -> Result<T, TupleError> {
70+
pub fn unpack<T: Decode>(&self, key: &[u8]) -> Result<T, tuple::Error> {
7171
if !self.is_start_of(key) {
72-
return Err(TupleError::InvalidData);
72+
return Err(tuple::Error::InvalidData);
7373
}
7474
let key = &key[self.prefix.len()..];
75-
Tuple::decode(&key)
75+
Decode::decode(&key)
7676
}
7777

7878
/// `is_start_of` returns true if the provided key starts with the prefix of this Subspace,
@@ -114,7 +114,7 @@ mod tests {
114114
let tup = (2, 3);
115115

116116
let packed = ss0.pack(&tup);
117-
let expected = Tuple::encode_to_vec(&(1, 2, 3));
117+
let expected = Encode::encode_to_vec(&(1, 2, 3));
118118
assert_eq!(expected, packed);
119119

120120
let tup_unpack: (i64, i64) = ss0.unpack(&packed).unwrap();

foundationdb/src/transaction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ impl RangeOptionBuilder {
100100
/// Create new builder with a tuple as a prefix
101101
pub fn from_tuple<T>(tup: &T) -> Self
102102
where
103-
T: tuple::Tuple,
103+
T: tuple::Encode,
104104
{
105-
let bytes = tuple::Tuple::encode_to_vec(tup);
105+
let bytes = tuple::Encode::encode_to_vec(tup);
106106
let mut begin = bytes.clone();
107107
begin.push(0x00);
108108

foundationdb/src/tuple/mod.rs

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
pub mod single;
1212

1313
use std::{self, io::Write, string::FromUtf8Error};
14-
use self::single::Single;
1514

1615
#[derive(Debug, Fail)]
1716
pub enum Error {
@@ -33,24 +32,26 @@ impl From<FromUtf8Error> for Error {
3332
}
3433
}
3534

36-
pub trait Tuple: Sized {
35+
pub trait Encode {
3736
fn encode<W: Write>(&self, _w: &mut W) -> std::io::Result<()>;
3837
fn encode_to_vec(&self) -> Vec<u8> {
3938
let mut v = Vec::new();
4039
self.encode(&mut v)
4140
.expect("tuple encoding should never fail");
4241
v
4342
}
43+
}
4444

45+
pub trait Decode: Sized {
4546
fn decode(buf: &[u8]) -> Result<Self>;
4647
}
4748

4849
macro_rules! tuple_impls {
4950
($($len:expr => ($($n:tt $name:ident)+))+) => {
5051
$(
51-
impl<$($name),+> Tuple for ($($name,)+)
52+
impl<$($name),+> Encode for ($($name,)+)
5253
where
53-
$($name: Single + Default,)+
54+
$($name: single::Encode + Default,)+
5455
{
5556
#[allow(non_snake_case, unused_assignments, deprecated)]
5657
fn encode<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
@@ -59,7 +60,12 @@ macro_rules! tuple_impls {
5960
)*
6061
Ok(())
6162
}
63+
}
6264

65+
impl<$($name),+> Decode for ($($name,)+)
66+
where
67+
$($name: single::Decode + Default,)+
68+
{
6369
#[allow(non_snake_case, unused_assignments, deprecated)]
6470
fn decode(buf: &[u8]) -> Result<Self> {
6571
let mut buf = buf;
@@ -99,22 +105,65 @@ tuple_impls! {
99105
#[derive(Clone, Debug, PartialEq)]
100106
pub struct Value(pub Vec<single::Value>);
101107

102-
impl Tuple for Value {
108+
impl Encode for Value {
103109
fn encode<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
110+
use self::single::Encode;
104111
for item in self.0.iter() {
105112
item.encode(w)?;
106113
}
107114
Ok(())
108115
}
116+
}
109117

118+
impl Decode for Value {
110119
fn decode(buf: &[u8]) -> Result<Self> {
111120
let mut data = buf;
112121
let mut v = Vec::new();
113122
while !data.is_empty() {
114-
let (s, offset): (single::Value, _) = Single::decode(data)?;
123+
let (s, offset): (single::Value, _) = single::Decode::decode(data)?;
115124
v.push(s);
116125
data = &data[offset..];
117126
}
118127
Ok(Value(v))
119128
}
120129
}
130+
131+
#[cfg(test)]
132+
mod tests {
133+
use super::*;
134+
135+
#[test]
136+
fn test_malformed_int() {
137+
assert!(Value::decode(&[21, 0]).is_ok());
138+
assert!(Value::decode(&[22, 0]).is_err());
139+
assert!(Value::decode(&[22, 0, 0]).is_ok());
140+
141+
assert!(Value::decode(&[19, 0]).is_ok());
142+
assert!(Value::decode(&[18, 0]).is_err());
143+
assert!(Value::decode(&[18, 0, 0]).is_ok());
144+
}
145+
146+
#[test]
147+
fn test_decode_tuple() {
148+
assert_eq!((0, ()), Decode::decode(&[20, 0]).unwrap());
149+
}
150+
151+
#[test]
152+
fn test_decode_tuple_ty() {
153+
let data: &[u8] = &[2, 104, 101, 108, 108, 111, 0, 1, 119, 111, 114, 108, 100, 0];
154+
155+
let (v1, v2): (String, Vec<u8>) = Decode::decode(data).unwrap();
156+
assert_eq!(v1, "hello");
157+
assert_eq!(v2, b"world");
158+
}
159+
160+
#[test]
161+
fn test_encode_tuple_ty() {
162+
let tup = (String::from("hello"), b"world".to_vec());
163+
164+
assert_eq!(
165+
&[2, 104, 101, 108, 108, 111, 0, 1, 119, 111, 114, 108, 100, 0],
166+
Encode::encode_to_vec(&tup).as_slice()
167+
);
168+
}
169+
}

0 commit comments

Comments
 (0)