implement Value::Blob type

without.crypto
Myk Melez 6 years ago
parent 9f0dfdc8a2
commit f942471d47
  1. 1
      Cargo.toml
  2. 39
      src/env.rs
  3. 13
      src/value.rs

@ -29,4 +29,5 @@ default_features = false
features = ["derive"]
[dev-dependencies]
byteorder = "1"
tempdir = "0.3"

@ -143,7 +143,9 @@ impl Rkv {
#[cfg(test)]
mod tests {
extern crate tempdir;
extern crate byteorder;
use self::byteorder::{ByteOrder, LittleEndian};
use self::tempdir::TempDir;
use std::fs;
@ -404,6 +406,43 @@ mod tests {
assert_eq!(reader.get("foo").expect("read"), Some(Value::I64(999)));
}
#[test]
fn test_blob() {
let root = TempDir::new("test_round_trip_blob").expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let sk: Store<&str> = k.create_or_open("sk").expect("opened");
let mut writer = sk.write(&k).expect("writer");
assert_eq!(writer.get("foo").expect("read"), None);
writer.put("foo", &Value::Blob(&[1, 2, 3, 4])).expect("wrote");
assert_eq!(writer.get("foo").expect("read"), Some(Value::Blob(&[1, 2, 3, 4])));
fn u16_to_u8(src: &[u16]) -> Vec<u8> {
let mut dst = vec![0; 2 * src.len()];
LittleEndian::write_u16_into(src, &mut dst);
dst
}
fn u8_to_u16(src: &[u8]) -> Vec<u16> {
let mut dst = vec![0; src.len() / 2];
LittleEndian::read_u16_into(src, &mut dst);
dst
}
// When storing UTF-16 strings as blobs, we'll need to convert
// their [u16] backing storage to [u8]. Test that converting, writing,
// reading, and converting back works as expected.
let u16_array = [1000, 10000, 54321, 65535];
assert_eq!(writer.get("bar").expect("read"), None);
writer.put("bar", &Value::Blob(&u16_to_u8(&u16_array))).expect("wrote");
let u8_array = match writer.get("bar").expect("read") {
Some(Value::Blob(val)) => val,
_ => &[],
};
assert_eq!(u8_to_u16(u8_array), u16_array);
}
#[test]
#[should_panic(expected = "not yet implemented")]
fn test_delete_value() {

@ -38,6 +38,7 @@ pub enum Type {
Uuid = 6,
Str = 7,
Json = 8,
Blob = 9,
}
/// We use manual tagging, because <https://github.com/serde-rs/serde/issues/610>.
@ -60,6 +61,7 @@ impl Type {
6 => Some(Type::Uuid),
7 => Some(Type::Str),
8 => Some(Type::Json),
9 => Some(Type::Blob),
_ => None,
}
}
@ -76,6 +78,7 @@ impl ::std::fmt::Display for Type {
Type::Uuid => "uuid",
Type::Str => "str",
Type::Json => "json",
Type::Blob => "blob",
})
}
}
@ -90,6 +93,7 @@ pub enum Value<'s> {
Uuid(&'s UuidBytes),
Str(&'s str),
Json(&'s str),
Blob(&'s [u8]),
}
// TODO: implement conversion between the two types of `Value` wrapper.
@ -103,6 +107,7 @@ enum OwnedValue {
Uuid(Uuid),
Str(String),
Json(String), // TODO
Blob(Vec<u8>),
}
fn uuid<'s>(bytes: &'s [u8]) -> Result<Value<'s>, DataError> {
@ -157,6 +162,9 @@ impl<'s> Value<'s> {
Type::Json => {
deserialize(data).map(Value::Json)
},
Type::Blob => {
deserialize(data).map(Value::Blob)
},
Type::Uuid => {
// Processed above to avoid verbose duplication of error transforms.
unreachable!()
@ -187,10 +195,13 @@ impl<'s> Value<'s> {
&Value::Json(ref v) => {
serialize(&(Type::Json.to_tag(), v), Infinite)
},
&Value::Blob(ref v) => {
serialize(&(Type::Blob.to_tag(), v), Infinite)
},
&Value::Uuid(ref v) => {
// Processed above to avoid verbose duplication of error transforms.
serialize(&(Type::Uuid.to_tag(), v), Infinite)
},
}.map_err(DataError::EncodingError)
}
}
}

Loading…
Cancel
Save