Replace all the passed-by-reference with passed-by-value for Store (#88)

* Replace all the passed-by-reference with passed-by-value for Store
* Remove unnecessary as_ref calls
* Simplify the function signature of iterator
without.crypto
Nan Jiang 6 years ago committed by Myk Melez
parent 69aadb5ffe
commit 43a8731ff8
  1. 10
      examples/iterator.rs
  2. 68
      examples/simple-store.rs
  3. 246
      src/env.rs
  4. 27
      src/integer.rs
  5. 58
      src/lib.rs
  6. 40
      src/readwrite.rs
  7. 4
      src/value.rs

@ -31,14 +31,14 @@ fn main() {
let k = created_arc.read().unwrap();
let store = k.open_or_create("store").unwrap();
populate_store(&k, &store).unwrap();
populate_store(&k, store).unwrap();
let reader = k.read().unwrap();
println!("Iterating from the beginning...");
// Reader::iter_start() iterates from the first item in the store, and
// returns the (key, value) tuples in order.
let mut iter = reader.iter_start(&store).unwrap();
let mut iter = reader.iter_start(store).unwrap();
while let Some((country, city)) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
@ -47,20 +47,20 @@ fn main() {
println!("Iterating from the given key...");
// Reader::iter_from() iterates from the first key equal to or greater
// than the given key.
let mut iter = reader.iter_from(&store, "Japan").unwrap();
let mut iter = reader.iter_from(store, "Japan").unwrap();
while let Some((country, city)) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
println!("");
println!("Iterating from the given prefix...");
let mut iter = reader.iter_from(&store, "Un").unwrap();
let mut iter = reader.iter_from(store, "Un").unwrap();
while let Some((country, city)) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
}
fn populate_store(k: &Rkv, store: &Store) -> Result<(), StoreError> {
fn populate_store(k: &Rkv, store: Store) -> Result<(), StoreError> {
let mut writer = k.write()?;
for (country, city) in vec![
("Canada", Value::Str("Ottawa")),

@ -35,14 +35,14 @@ fn main() {
{
// Use a writer to mutate the store
let mut writer = k.write().unwrap();
writer.put(&store, "int", &Value::I64(1234)).unwrap();
writer.put(&store, "uint", &Value::U64(1234_u64)).unwrap();
writer.put(&store, "float", &Value::F64(1234.0.into())).unwrap();
writer.put(&store, "instant", &Value::Instant(1528318073700)).unwrap();
writer.put(&store, "boolean", &Value::Bool(true)).unwrap();
writer.put(&store, "string", &Value::Str("héllo, yöu")).unwrap();
writer.put(&store, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
writer.put(&store, "blob", &Value::Blob(b"blob")).unwrap();
writer.put(store, "int", &Value::I64(1234)).unwrap();
writer.put(store, "uint", &Value::U64(1234_u64)).unwrap();
writer.put(store, "float", &Value::F64(1234.0.into())).unwrap();
writer.put(store, "instant", &Value::Instant(1528318073700)).unwrap();
writer.put(store, "boolean", &Value::Bool(true)).unwrap();
writer.put(store, "string", &Value::Str("héllo, yöu")).unwrap();
writer.put(store, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
writer.put(store, "blob", &Value::Blob(b"blob")).unwrap();
writer.commit().unwrap();
}
@ -50,40 +50,40 @@ fn main() {
{
// Use a reader to query the store
let reader = k.read().unwrap();
println!("Get int {:?}", reader.get(&store, "int").unwrap());
println!("Get uint {:?}", reader.get(&store, "uint").unwrap());
println!("Get float {:?}", reader.get(&store, "float").unwrap());
println!("Get instant {:?}", reader.get(&store, "instant").unwrap());
println!("Get boolean {:?}", reader.get(&store, "boolean").unwrap());
println!("Get string {:?}", reader.get(&store, "string").unwrap());
println!("Get json {:?}", reader.get(&store, "json").unwrap());
println!("Get blob {:?}", reader.get(&store, "blob").unwrap());
println!("Get non-existent {:?}", reader.get(&store, "non-existent").unwrap());
println!("Get int {:?}", reader.get(store, "int").unwrap());
println!("Get uint {:?}", reader.get(store, "uint").unwrap());
println!("Get float {:?}", reader.get(store, "float").unwrap());
println!("Get instant {:?}", reader.get(store, "instant").unwrap());
println!("Get boolean {:?}", reader.get(store, "boolean").unwrap());
println!("Get string {:?}", reader.get(store, "string").unwrap());
println!("Get json {:?}", reader.get(store, "json").unwrap());
println!("Get blob {:?}", reader.get(store, "blob").unwrap());
println!("Get non-existent {:?}", reader.get(store, "non-existent").unwrap());
}
println!("Looking up keys via Writer.get()...");
{
let mut writer = k.write().unwrap();
writer.put(&store, "foo", &Value::Str("bar")).unwrap();
writer.put(&store, "bar", &Value::Str("baz")).unwrap();
writer.delete(&store, "foo").unwrap();
println!("It should be None! ({:?})", writer.get(&store, "foo").unwrap());
println!("Get bar ({:?})", writer.get(&store, "bar").unwrap());
writer.put(store, "foo", &Value::Str("bar")).unwrap();
writer.put(store, "bar", &Value::Str("baz")).unwrap();
writer.delete(store, "foo").unwrap();
println!("It should be None! ({:?})", writer.get(store, "foo").unwrap());
println!("Get bar ({:?})", writer.get(store, "bar").unwrap());
writer.commit().unwrap();
let reader = k.read().expect("reader");
println!("It should be None! ({:?})", reader.get(&store, "foo").unwrap());
println!("Get bar {:?}", reader.get(&store, "bar").unwrap());
println!("It should be None! ({:?})", reader.get(store, "foo").unwrap());
println!("Get bar {:?}", reader.get(store, "bar").unwrap());
}
println!("Aborting transaction...");
{
// Aborting a write transaction rollbacks the change(s)
let mut writer = k.write().unwrap();
writer.put(&store, "foo", &Value::Str("bar")).unwrap();
writer.put(store, "foo", &Value::Str("bar")).unwrap();
writer.abort();
let reader = k.read().expect("reader");
println!("It should be None! ({:?})", reader.get(&store, "foo").unwrap());
println!("It should be None! ({:?})", reader.get(store, "foo").unwrap());
// Explicitly aborting a transaction is not required unless an early
// abort is desired, since both read and write transactions will
// implicitly be aborted once they go out of scope.
@ -93,27 +93,27 @@ fn main() {
{
// Deleting a key/value also requires a write transaction
let mut writer = k.write().unwrap();
writer.put(&store, "foo", &Value::Str("bar")).unwrap();
writer.delete(&store, "foo").unwrap();
println!("It should be None! ({:?})", writer.get(&store, "foo").unwrap());
writer.put(store, "foo", &Value::Str("bar")).unwrap();
writer.delete(store, "foo").unwrap();
println!("It should be None! ({:?})", writer.get(store, "foo").unwrap());
writer.commit().unwrap();
// Committing a transaction consumes the writer, preventing you
// from reusing it by failing and reporting a compile-time error.
// This line would report error[E0382]: use of moved value: `writer`.
// writer.put(&store, "baz", &Value::Str("buz")).unwrap();
// writer.put(store, "baz", &Value::Str("buz")).unwrap();
}
println!("Write and read on multiple stores...");
{
let another_store = k.open_or_create("another_store").unwrap();
let mut writer = k.write().unwrap();
writer.put(&store, "foo", &Value::Str("bar")).unwrap();
writer.put(&another_store, "foo", &Value::Str("baz")).unwrap();
writer.put(store, "foo", &Value::Str("bar")).unwrap();
writer.put(another_store, "foo", &Value::Str("baz")).unwrap();
writer.commit().unwrap();
let reader = k.read().unwrap();
println!("Get from store value: {:?}", reader.get(&store, "foo").unwrap());
println!("Get from another store value: {:?}", reader.get(&another_store, "foo").unwrap());
println!("Get from store value: {:?}", reader.get(store, "foo").unwrap());
println!("Get from another store value: {:?}", reader.get(another_store, "foo").unwrap());
}
}

@ -227,7 +227,7 @@ mod tests {
let yyy = k.open_or_create("yyy").expect("opened");
let reader = k.read().expect("reader");
let result = reader.get(&yyy, "foo");
let result = reader.get(yyy, "foo");
assert_eq!(None, result.expect("success but no value"));
}
@ -305,7 +305,7 @@ mod tests {
// We write a string that is larger than the default map size.
let val = "x".repeat(get_larger_than_default_map_size_value());
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::Str(&val)).expect("wrote");
writer.put(sk, "foo", &Value::Str(&val)).expect("wrote");
}
#[test]
@ -324,11 +324,11 @@ mod tests {
let val = "x".repeat(get_larger_than_default_map_size_value());
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::Str(&val)).expect("wrote");
writer.put(sk, "foo", &Value::Str(&val)).expect("wrote");
writer.commit().expect("committed");
let reader = k.read().unwrap();
assert_eq!(reader.get(&sk, "foo").expect("read"), Some(Value::Str(&val)));
assert_eq!(reader.get(sk, "foo").expect("read"), Some(Value::Str(&val)));
}
#[test]
@ -341,39 +341,39 @@ mod tests {
{
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(&sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
assert_eq!(writer.get(&sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(&sk, "noo").expect("read"), Some(Value::F64(1234.0.into())));
assert_eq!(writer.get(&sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(writer.get(&sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
writer.put(sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
assert_eq!(writer.get(sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(sk, "noo").expect("read"), Some(Value::F64(1234.0.into())));
assert_eq!(writer.get(sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(writer.get(sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
// Isolation. Reads won't return values.
let r = &k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), None);
assert_eq!(r.get(&sk, "bar").expect("read"), None);
assert_eq!(r.get(&sk, "baz").expect("read"), None);
assert_eq!(r.get(sk, "foo").expect("read"), None);
assert_eq!(r.get(sk, "bar").expect("read"), None);
assert_eq!(r.get(sk, "baz").expect("read"), None);
}
// Dropped: tx rollback. Reads will still return nothing.
{
let r = &k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), None);
assert_eq!(r.get(&sk, "bar").expect("read"), None);
assert_eq!(r.get(&sk, "baz").expect("read"), None);
assert_eq!(r.get(sk, "foo").expect("read"), None);
assert_eq!(r.get(sk, "bar").expect("read"), None);
assert_eq!(r.get(sk, "baz").expect("read"), None);
}
{
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
assert_eq!(writer.get(&sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(&sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(writer.get(&sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
writer.put(sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
assert_eq!(writer.get(sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(writer.get(sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
writer.commit().expect("committed");
}
@ -381,44 +381,44 @@ mod tests {
// Committed. Reads will succeed.
{
let r = k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(&sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(&sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
assert_eq!(r.get(sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
}
{
let mut writer = k.write().expect("writer");
writer.delete(&sk, "foo").expect("deleted");
writer.delete(&sk, "bar").expect("deleted");
writer.delete(&sk, "baz").expect("deleted");
assert_eq!(writer.get(&sk, "foo").expect("read"), None);
assert_eq!(writer.get(&sk, "bar").expect("read"), None);
assert_eq!(writer.get(&sk, "baz").expect("read"), None);
writer.delete(sk, "foo").expect("deleted");
writer.delete(sk, "bar").expect("deleted");
writer.delete(sk, "baz").expect("deleted");
assert_eq!(writer.get(sk, "foo").expect("read"), None);
assert_eq!(writer.get(sk, "bar").expect("read"), None);
assert_eq!(writer.get(sk, "baz").expect("read"), None);
// Isolation. Reads still return values.
let r = k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(&sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(&sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
assert_eq!(r.get(sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
}
// Dropped: tx rollback. Reads will still return values.
{
let r = k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(&sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(&sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
assert_eq!(r.get(sk, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(r.get(sk, "bar").expect("read"), Some(Value::Bool(true)));
assert_eq!(r.get(sk, "baz").expect("read"), Some(Value::Str("héllo, yöu")));
}
{
let mut writer = k.write().expect("writer");
writer.delete(&sk, "foo").expect("deleted");
writer.delete(&sk, "bar").expect("deleted");
writer.delete(&sk, "baz").expect("deleted");
assert_eq!(writer.get(&sk, "foo").expect("read"), None);
assert_eq!(writer.get(&sk, "bar").expect("read"), None);
assert_eq!(writer.get(&sk, "baz").expect("read"), None);
writer.delete(sk, "foo").expect("deleted");
writer.delete(sk, "bar").expect("deleted");
writer.delete(sk, "baz").expect("deleted");
assert_eq!(writer.get(sk, "foo").expect("read"), None);
assert_eq!(writer.get(sk, "bar").expect("read"), None);
assert_eq!(writer.get(sk, "baz").expect("read"), None);
writer.commit().expect("committed");
}
@ -426,9 +426,9 @@ mod tests {
// Committed. Reads will succeed but return None to indicate a missing value.
{
let r = k.read().unwrap();
assert_eq!(r.get(&sk, "foo").expect("read"), None);
assert_eq!(r.get(&sk, "bar").expect("read"), None);
assert_eq!(r.get(&sk, "baz").expect("read"), None);
assert_eq!(r.get(sk, "foo").expect("read"), None);
assert_eq!(r.get(sk, "bar").expect("read"), None);
assert_eq!(r.get(sk, "baz").expect("read"), None);
}
}
@ -440,7 +440,7 @@ mod tests {
// First create the store, and start a write transaction on it.
let sk = k.open_or_create("sk").expect("opened");
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::Str("bar")).expect("write");
writer.put(sk, "foo", &Value::Str("bar")).expect("write");
// Open the same store for read, note that the write transaction is still in progress,
// it should not block the reader though.
@ -448,7 +448,7 @@ mod tests {
writer.commit().expect("commit");
// Now the write transaction is committed, any followed reads should see its change.
let reader = k.read().expect("reader");
assert_eq!(reader.get(&sk_readonly, "foo").expect("read"), Some(Value::Str("bar")));
assert_eq!(reader.get(sk_readonly, "foo").expect("read"), Some(Value::Str("bar")));
}
#[test]
@ -489,7 +489,7 @@ mod tests {
// as the Value::I64 borrows an immutable reference to the Writer.
// So we extract and copy its primitive value.
fn get_existing_foo(writer: &Writer<&str>, store: &Store) -> Option<i64> {
fn get_existing_foo(writer: &Writer<&str>, store: Store) -> Option<i64> {
match writer.get(store, "foo").expect("read") {
Some(Value::I64(val)) => Some(val),
_ => None,
@ -497,11 +497,11 @@ mod tests {
}
let mut writer = k.write().expect("writer");
let mut existing = get_existing_foo(&writer, &sk).unwrap_or(99);
let mut existing = get_existing_foo(&writer, sk).unwrap_or(99);
existing += 1;
writer.put(&sk, "foo", &Value::I64(existing)).expect("success");
writer.put(sk, "foo", &Value::I64(existing)).expect("success");
let updated = get_existing_foo(&writer, &sk).unwrap_or(99);
let updated = get_existing_foo(&writer, sk).unwrap_or(99);
assert_eq!(updated, 100);
writer.commit().expect("commit");
}
@ -519,12 +519,12 @@ mod tests {
// reference to the Writer. So we copy it to a String.
let mut writer = k.write().expect("writer");
let mut existing = match writer.get(&sk, "foo").expect("read") {
let mut existing = match writer.get(sk, "foo").expect("read") {
Some(Value::Str(val)) => val,
_ => "",
}.to_string();
existing.push('…');
writer.put(&sk, "foo", &Value::Str(&existing)).expect("write");
writer.put(sk, "foo", &Value::Str(&existing)).expect("write");
writer.commit().expect("commit");
}
@ -557,36 +557,36 @@ mod tests {
// Add one field.
{
let mut writer = k.write().expect("writer");
writer.put(&s, "foo", &Value::I64(1234)).expect("wrote");
writer.put(s, "foo", &Value::I64(1234)).expect("wrote");
writer.commit().expect("committed");
}
{
let reader = k.read().unwrap();
assert_eq!(reader.get(&s, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(reader.get(s, "foo").expect("read"), Some(Value::I64(1234)));
}
// Establish a long-lived reader that outlasts a writer.
let reader = k.read().expect("reader");
assert_eq!(reader.get(&s, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(reader.get(s, "foo").expect("read"), Some(Value::I64(1234)));
// Start a write transaction.
let mut writer = k.write().expect("writer");
writer.put(&s, "foo", &Value::I64(999)).expect("wrote");
writer.put(s, "foo", &Value::I64(999)).expect("wrote");
// The reader and writer are isolated.
assert_eq!(reader.get(&s, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(&s, "foo").expect("read"), Some(Value::I64(999)));
assert_eq!(reader.get(s, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(writer.get(s, "foo").expect("read"), Some(Value::I64(999)));
// If we commit the writer, we still have isolation.
writer.commit().expect("committed");
assert_eq!(reader.get(&s, "foo").expect("read"), Some(Value::I64(1234)));
assert_eq!(reader.get(s, "foo").expect("read"), Some(Value::I64(1234)));
// A new reader sees the committed value. Note that LMDB doesn't allow two
// read transactions to exist in the same thread, so we abort the previous one.
reader.abort();
let reader = k.read().expect("reader");
assert_eq!(reader.get(&s, "foo").expect("read"), Some(Value::I64(999)));
assert_eq!(reader.get(s, "foo").expect("read"), Some(Value::I64(999)));
}
#[test]
@ -597,9 +597,9 @@ mod tests {
let sk: Store = k.open_or_create("sk").expect("opened");
let mut writer = k.write().expect("writer");
assert_eq!(writer.get(&sk, "foo").expect("read"), None);
writer.put(&sk, "foo", &Value::Blob(&[1, 2, 3, 4])).expect("wrote");
assert_eq!(writer.get(&sk, "foo").expect("read"), Some(Value::Blob(&[1, 2, 3, 4])));
assert_eq!(writer.get(sk, "foo").expect("read"), None);
writer.put(sk, "foo", &Value::Blob(&[1, 2, 3, 4])).expect("wrote");
assert_eq!(writer.get(sk, "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()];
@ -617,9 +617,9 @@ mod tests {
// 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(&sk, "bar").expect("read"), None);
writer.put(&sk, "bar", &Value::Blob(&u16_to_u8(&u16_array))).expect("wrote");
let u8_array = match writer.get(&sk, "bar").expect("read") {
assert_eq!(writer.get(sk, "bar").expect("read"), None);
writer.put(sk, "bar", &Value::Blob(&u16_to_u8(&u16_array))).expect("wrote");
let u8_array = match writer.get(sk, "bar").expect("read") {
Some(Value::Blob(val)) => val,
_ => &[],
};
@ -635,9 +635,9 @@ mod tests {
let sk: Store = k.open_or_create_with_flags("sk", DatabaseFlags::DUP_SORT).expect("opened");
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&sk, "foo", &Value::I64(1235)).expect("wrote");
writer.delete_value(&sk, "foo", &Value::I64(1234)).expect("deleted");
writer.put(sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(sk, "foo", &Value::I64(1235)).expect("wrote");
writer.delete_value(sk, "foo", &Value::I64(1234)).expect("deleted");
}
#[test]
@ -650,23 +650,23 @@ mod tests {
// An iterator over an empty store returns no values.
{
let reader = k.read::<&str>().unwrap();
let mut iter = reader.iter_start(&sk).unwrap();
let mut iter = reader.iter_start(sk).unwrap();
assert!(iter.next().is_none());
}
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(&sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(&sk, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(&sk, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
writer.put(sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(sk, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(sk, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
writer.commit().expect("committed");
let reader = k.read().unwrap();
// Reader.iter() returns (key, value) tuples ordered by key.
let mut iter = reader.iter_start(&sk).unwrap();
let mut iter = reader.iter_start(sk).unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "bar");
assert_eq!(val.expect("value"), Some(Value::Bool(true)));
@ -693,7 +693,7 @@ mod tests {
// Reader.iter_from() begins iteration at the first key equal to
// or greater than the given key.
let mut iter = reader.iter_from(&sk, "moo").unwrap();
let mut iter = reader.iter_from(sk, "moo").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -704,7 +704,7 @@ mod tests {
// Reader.iter_from() works as expected when the given key is a prefix
// of a key in the store.
let mut iter = reader.iter_from(&sk, "no").unwrap();
let mut iter = reader.iter_from(sk, "no").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -722,14 +722,14 @@ mod tests {
let sk: Store = k.open_or_create("sk").expect("opened");
let mut writer = k.write().expect("writer");
writer.put(&sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(&sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(sk, "foo", &Value::I64(1234)).expect("wrote");
writer.put(sk, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(sk, "bar", &Value::Bool(true)).expect("wrote");
writer.put(sk, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.commit().expect("committed");
let reader = k.read().unwrap();
let mut iter = reader.iter_from(&sk, "nuu").unwrap();
let mut iter = reader.iter_from(sk, "nuu").unwrap();
assert!(iter.next().is_none());
}
@ -744,33 +744,33 @@ mod tests {
let s3: Store = k.open_or_create("store_3").expect("opened");
let mut writer = k.write().expect("writer");
writer.put(&s1, "foo", &Value::Str("bar")).expect("wrote");
writer.put(&s2, "foo", &Value::I64(123)).expect("wrote");
writer.put(&s3, "foo", &Value::Bool(true)).expect("wrote");
writer.put(s1, "foo", &Value::Str("bar")).expect("wrote");
writer.put(s2, "foo", &Value::I64(123)).expect("wrote");
writer.put(s3, "foo", &Value::Bool(true)).expect("wrote");
assert_eq!(writer.get(&s1, "foo").expect("read"), Some(Value::Str("bar")));
assert_eq!(writer.get(&s2, "foo").expect("read"), Some(Value::I64(123)));
assert_eq!(writer.get(&s3, "foo").expect("read"), Some(Value::Bool(true)));
assert_eq!(writer.get(s1, "foo").expect("read"), Some(Value::Str("bar")));
assert_eq!(writer.get(s2, "foo").expect("read"), Some(Value::I64(123)));
assert_eq!(writer.get(s3, "foo").expect("read"), Some(Value::Bool(true)));
writer.commit().expect("committed");
let reader = k.read().expect("unbound_reader");
assert_eq!(reader.get(&s1, "foo").expect("read"), Some(Value::Str("bar")));
assert_eq!(reader.get(&s2, "foo").expect("read"), Some(Value::I64(123)));
assert_eq!(reader.get(&s3, "foo").expect("read"), Some(Value::Bool(true)));
assert_eq!(reader.get(s1, "foo").expect("read"), Some(Value::Str("bar")));
assert_eq!(reader.get(s2, "foo").expect("read"), Some(Value::I64(123)));
assert_eq!(reader.get(s3, "foo").expect("read"), Some(Value::Bool(true)));
reader.abort();
// test delete across multiple stores
let mut writer = k.write().expect("writer");
writer.delete(&s1, "foo").expect("deleted");
writer.delete(&s2, "foo").expect("deleted");
writer.delete(&s3, "foo").expect("deleted");
writer.delete(s1, "foo").expect("deleted");
writer.delete(s2, "foo").expect("deleted");
writer.delete(s3, "foo").expect("deleted");
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!(reader.get(&s1, "key").expect("value"), None);
assert_eq!(reader.get(&s2, "key").expect("value"), None);
assert_eq!(reader.get(&s3, "key").expect("value"), None);
assert_eq!(reader.get(s1, "key").expect("value"), None);
assert_eq!(reader.get(s2, "key").expect("value"), None);
assert_eq!(reader.get(s3, "key").expect("value"), None);
}
#[test]
@ -783,25 +783,25 @@ mod tests {
let mut writer = k.write().expect("writer");
// Write to "s1"
writer.put(&s1, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&s1, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(&s1, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&s1, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(&s1, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(&s1, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
writer.put(s1, "foo", &Value::I64(1234)).expect("wrote");
writer.put(s1, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(s1, "bar", &Value::Bool(true)).expect("wrote");
writer.put(s1, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(s1, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(s1, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
// Writer to "s2"
writer.put(&s2, "foo", &Value::I64(1234)).expect("wrote");
writer.put(&s2, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(&s2, "bar", &Value::Bool(true)).expect("wrote");
writer.put(&s2, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(&s2, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(&s2, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
writer.put(s2, "foo", &Value::I64(1234)).expect("wrote");
writer.put(s2, "noo", &Value::F64(1234.0.into())).expect("wrote");
writer.put(s2, "bar", &Value::Bool(true)).expect("wrote");
writer.put(s2, "baz", &Value::Str("héllo, yöu")).expect("wrote");
writer.put(s2, "héllò, töűrîst", &Value::Str("Emil.RuleZ!")).expect("wrote");
writer.put(s2, "你好,遊客", &Value::Str("米克規則")).expect("wrote");
writer.commit().expect("committed");
let reader = k.read().unwrap();
// Iterate through the whole store in "s1"
let mut iter = reader.iter_start(&s1).unwrap();
let mut iter = reader.iter_start(s1).unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "bar");
assert_eq!(val.expect("value"), Some(Value::Bool(true)));
@ -823,7 +823,7 @@ mod tests {
assert!(iter.next().is_none());
// Iterate through the whole store in "s2"
let mut iter = reader.iter_start(&s2).unwrap();
let mut iter = reader.iter_start(s2).unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "bar");
assert_eq!(val.expect("value"), Some(Value::Bool(true)));
@ -845,7 +845,7 @@ mod tests {
assert!(iter.next().is_none());
// Iterate from a given key in "s1"
let mut iter = reader.iter_from(&s1, "moo").unwrap();
let mut iter = reader.iter_from(s1, "moo").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -855,7 +855,7 @@ mod tests {
assert!(iter.next().is_none());
// Iterate from a given key in "s2"
let mut iter = reader.iter_from(&s2, "moo").unwrap();
let mut iter = reader.iter_from(s2, "moo").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -865,7 +865,7 @@ mod tests {
assert!(iter.next().is_none());
// Iterate from a given prefix in "s1"
let mut iter = reader.iter_from(&s1, "no").unwrap();
let mut iter = reader.iter_from(s1, "no").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -875,7 +875,7 @@ mod tests {
assert!(iter.next().is_none());
// Iterate from a given prefix in "s2"
let mut iter = reader.iter_from(&s2, "no").unwrap();
let mut iter = reader.iter_from(s2, "no").unwrap();
let (key, val) = iter.next().unwrap();
assert_eq!(str::from_utf8(key).expect("key"), "noo");
assert_eq!(val.expect("value"), Some(Value::F64(1234.0.into())));
@ -907,7 +907,7 @@ mod tests {
write_handles.push(thread::spawn(move || {
let rkv = rkv_arc.write().expect("rkv");
let mut writer = rkv.write().expect("writer");
writer.put(&store, i.to_string(), &Value::U64(i)).expect("written");
writer.put(store, i.to_string(), &Value::U64(i)).expect("written");
writer.commit().unwrap();
}));
}
@ -922,7 +922,7 @@ mod tests {
read_handles.push(thread::spawn(move || {
let rkv = rkv_arc.read().expect("rkv");
let reader = rkv.read().expect("reader");
let value = match reader.get(&store, i.to_string()) {
let value = match reader.get(store, i.to_string()) {
Ok(Some(Value::U64(value))) => value,
Ok(Some(_)) => panic!("value type unexpected"),
Ok(None) => panic!("value not found"),

@ -90,8 +90,8 @@ where
}
}
pub fn get<'s>(&'s self, store: &'s IntegerStore, k: K) -> Result<Option<Value<'s>>, StoreError> {
self.inner.get(&store.inner, Key::new(k)?)
pub fn get(&self, store: IntegerStore, k: K) -> Result<Option<Value>, StoreError> {
self.inner.get(store.0, Key::new(k)?)
}
pub fn abort(self) {
@ -116,12 +116,12 @@ where
}
}
pub fn get<'s>(&'s self, store: &'s IntegerStore, k: K) -> Result<Option<Value<'s>>, StoreError> {
self.inner.get(&store.inner, Key::new(k)?)
pub fn get(&self, store: IntegerStore, k: K) -> Result<Option<Value>, StoreError> {
self.inner.get(store.0, Key::new(k)?)
}
pub fn put<'s>(&'s mut self, store: &'s IntegerStore, k: K, v: &Value) -> Result<(), StoreError> {
self.inner.put(&store.inner, Key::new(k)?, v)
pub fn put(&mut self, store: IntegerStore, k: K, v: &Value) -> Result<(), StoreError> {
self.inner.put(store.0, Key::new(k)?, v)
}
fn abort(self) {
@ -133,15 +133,12 @@ where
}
}
pub struct IntegerStore {
inner: Store,
}
#[derive(Copy, Clone)]
pub struct IntegerStore(Store);
impl IntegerStore {
pub fn new(db: Database) -> IntegerStore {
IntegerStore {
inner: Store::new(db),
}
IntegerStore(Store::new(db))
}
}
@ -164,11 +161,11 @@ mod tests {
let mut writer = k.write_int::<u32>().expect("writer");
writer.put(&s, 123, &Value::Str("hello!")).expect("write");
assert_eq!(writer.get(&s, 123).expect("read"), Some(Value::Str("hello!")));
writer.put(s, 123, &Value::Str("hello!")).expect("write");
assert_eq!(writer.get(s, 123).expect("read"), Some(Value::Str("hello!")));
writer.commit().expect("committed");
let reader = k.read_int::<u32>().expect("reader");
assert_eq!(reader.get(&s, 123).expect("read"), Some(Value::Str("hello!")));
assert_eq!(reader.get(s, 123).expect("read"), Some(Value::Str("hello!")));
}
}

@ -79,14 +79,14 @@
//! // Writer takes a `Store` reference as the first argument.
//! // Keys are `AsRef<[u8]>`, while values are `Value` enum instances.
//! // Use the `Blob` variant to store arbitrary collections of bytes.
//! writer.put(&store, "int", &Value::I64(1234)).unwrap();
//! writer.put(&store, "uint", &Value::U64(1234_u64)).unwrap();
//! writer.put(&store, "float", &Value::F64(1234.0.into())).unwrap();
//! writer.put(&store, "instant", &Value::Instant(1528318073700)).unwrap();
//! writer.put(&store, "boolean", &Value::Bool(true)).unwrap();
//! writer.put(&store, "string", &Value::Str("héllo, yöu")).unwrap();
//! writer.put(&store, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
//! writer.put(&store, "blob", &Value::Blob(b"blob")).unwrap();
//! writer.put(store, "int", &Value::I64(1234)).unwrap();
//! writer.put(store, "uint", &Value::U64(1234_u64)).unwrap();
//! writer.put(store, "float", &Value::F64(1234.0.into())).unwrap();
//! writer.put(store, "instant", &Value::Instant(1528318073700)).unwrap();
//! writer.put(store, "boolean", &Value::Bool(true)).unwrap();
//! writer.put(store, "string", &Value::Str("héllo, yöu")).unwrap();
//! writer.put(store, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
//! writer.put(store, "blob", &Value::Blob(b"blob")).unwrap();
//!
//! // You must commit a write transaction before the writer goes out
//! // of scope, or the transaction will abort and the data won't persist.
@ -101,17 +101,17 @@
//!
//! // To retrieve data, call `Reader.get()`, passing it the target store
//! // and the key for the value to retrieve.
//! println!("Get int {:?}", reader.get(&store, "int").unwrap());
//! println!("Get uint {:?}", reader.get(&store, "uint").unwrap());
//! println!("Get float {:?}", reader.get(&store, "float").unwrap());
//! println!("Get instant {:?}", reader.get(&store, "instant").unwrap());
//! println!("Get boolean {:?}", reader.get(&store, "boolean").unwrap());
//! println!("Get string {:?}", reader.get(&store, "string").unwrap());
//! println!("Get json {:?}", reader.get(&store, "json").unwrap());
//! println!("Get blob {:?}", reader.get(&store, "blob").unwrap());
//! println!("Get int {:?}", reader.get(store, "int").unwrap());
//! println!("Get uint {:?}", reader.get(store, "uint").unwrap());
//! println!("Get float {:?}", reader.get(store, "float").unwrap());
//! println!("Get instant {:?}", reader.get(store, "instant").unwrap());
//! println!("Get boolean {:?}", reader.get(store, "boolean").unwrap());
//! println!("Get string {:?}", reader.get(store, "string").unwrap());
//! println!("Get json {:?}", reader.get(store, "json").unwrap());
//! println!("Get blob {:?}", reader.get(store, "blob").unwrap());
//!
//! // Retrieving a non-existent value returns `Ok(None)`.
//! println!("Get non-existent value {:?}", reader.get(&store, "non-existent"));
//! println!("Get non-existent value {:?}", reader.get(store, "non-existent"));
//!
//! // A read transaction will automatically close once the reader
//! // goes out of scope, so isn't necessary to close it explicitly,
@ -121,11 +121,11 @@
//! {
//! // Aborting a write transaction rolls back the change(s).
//! let mut writer = env.write().unwrap();
//! writer.put(&store, "foo", &Value::Str("bar")).unwrap();
//! writer.put(store, "foo", &Value::Str("bar")).unwrap();
//! writer.abort();
//!
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", reader.get(&store, "foo").unwrap());
//! println!("It should be None! ({:?})", reader.get(store, "foo").unwrap());
//! }
//!
//! {
@ -134,35 +134,35 @@
//! // implicitly be aborted once they go out of scope.
//! {
//! let mut writer = env.write().unwrap();
//! writer.put(&store, "foo", &Value::Str("bar")).unwrap();
//! writer.put(store, "foo", &Value::Str("bar")).unwrap();
//! }
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", reader.get(&store, "foo").unwrap());
//! println!("It should be None! ({:?})", reader.get(store, "foo").unwrap());
//! }
//!
//! {
//! // Deleting a key/value pair also requires a write transaction.
//! let mut writer = env.write().unwrap();
//! writer.put(&store, "foo", &Value::Str("bar")).unwrap();
//! writer.put(&store, "bar", &Value::Str("baz")).unwrap();
//! writer.delete(&store, "foo").unwrap();
//! writer.put(store, "foo", &Value::Str("bar")).unwrap();
//! writer.put(store, "bar", &Value::Str("baz")).unwrap();
//! writer.delete(store, "foo").unwrap();
//!
//! // A write transaction also supports reading, the version of the
//! // store that it reads includes changes it has made regardless of
//! // the commit state of that transaction.
//! // In the code above, "foo" and "bar" were put into the store,
//! // then "foo" was deleted so only "bar" will return a result.
//! println!("It should be None! ({:?})", writer.get(&store, "foo").unwrap());
//! println!("Get bar ({:?})", writer.get(&store, "bar").unwrap());
//! println!("It should be None! ({:?})", writer.get(store, "foo").unwrap());
//! println!("Get bar ({:?})", writer.get(store, "bar").unwrap());
//! writer.commit().unwrap();
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", reader.get(&store, "foo").unwrap());
//! println!("Get bar {:?}", reader.get(&store, "bar").unwrap());
//! println!("It should be None! ({:?})", reader.get(store, "foo").unwrap());
//! println!("Get bar {:?}", reader.get(store, "bar").unwrap());
//!
//! // Committing a transaction consumes the writer, preventing you
//! // from reusing it by failing at compile time with an error.
//! // This line would report error[E0382]: use of moved value: `writer`.
//! // writer.put(&store, "baz", &Value::Str("buz")).unwrap();
//! // writer.put(store, "baz", &Value::Str("buz")).unwrap();
//! }
//! ```

@ -28,7 +28,7 @@ use error::StoreError;
use value::Value;
fn read_transform<'x>(val: Result<&'x [u8], lmdb::Error>) -> Result<Option<Value<'x>>, StoreError> {
fn read_transform(val: Result<&[u8], lmdb::Error>) -> Result<Option<Value>, StoreError> {
match val {
Ok(bytes) => Value::from_tagged_slice(bytes).map(Some).map_err(StoreError::DataError),
Err(lmdb::Error::NotFound) => Ok(None),
@ -68,23 +68,23 @@ where
}
}
pub fn get<'s>(&'s self, store: &'s Store, k: K) -> Result<Option<Value<'s>>, StoreError> {
let bytes = self.tx.get(store.db, &k.as_ref());
pub fn get(&self, store: Store, k: K) -> Result<Option<Value>, StoreError> {
let bytes = self.tx.get(store.0, &k);
read_transform(bytes)
}
// TODO: flags
pub fn put<'s>(&'s mut self, store: &'s Store, k: K, v: &Value) -> Result<(), StoreError> {
pub fn put(&mut self, store: Store, k: K, v: &Value) -> Result<(), StoreError> {
// TODO: don't allocate twice.
let bytes = v.to_bytes()?;
self.tx.put(store.db, &k.as_ref(), &bytes, WriteFlags::empty()).map_err(StoreError::LmdbError)
self.tx.put(store.0, &k, &bytes, WriteFlags::empty()).map_err(StoreError::LmdbError)
}
pub fn delete<'s>(&'s mut self, store: &'s Store, k: K) -> Result<(), StoreError> {
self.tx.del(store.db, &k.as_ref(), None).map_err(StoreError::LmdbError)
pub fn delete(&mut self, store: Store, k: K) -> Result<(), StoreError> {
self.tx.del(store.0, &k, None).map_err(StoreError::LmdbError)
}
pub fn delete_value<'s>(&'s mut self, _store: &'s Store, _k: K, _v: &Value) -> Result<(), StoreError> {
pub fn delete_value(&mut self, _store: Store, _k: K, _v: &Value) -> Result<(), StoreError> {
// Even better would be to make this a method only on a dupsort store —
// it would need a little bit of reorganizing of types and traits,
// but when I see "If the database does not support sorted duplicate
@ -113,8 +113,8 @@ where
}
}
pub fn get<'s>(&'s self, store: &'s Store, k: K) -> Result<Option<Value<'s>>, StoreError> {
let bytes = self.tx.get(store.db, &k.as_ref());
pub fn get(&self, store: Store, k: K) -> Result<Option<Value>, StoreError> {
let bytes = self.tx.get(store.0, &k);
read_transform(bytes)
}
@ -122,8 +122,8 @@ where
self.tx.abort();
}
pub fn iter_start<'s>(&'s self, store: &'s Store) -> Result<Iter<'s>, StoreError> {
let mut cursor = self.tx.open_ro_cursor(store.db).map_err(StoreError::LmdbError)?;
pub fn iter_start(&self, store: Store) -> Result<Iter, StoreError> {
let mut cursor = self.tx.open_ro_cursor(store.0).map_err(StoreError::LmdbError)?;
// We call Cursor.iter() instead of Cursor.iter_start() because
// the latter panics at "called `Result::unwrap()` on an `Err` value:
@ -141,8 +141,8 @@ where
})
}
pub fn iter_from<'s>(&'s self, store: &'s Store, k: K) -> Result<Iter<'s>, StoreError> {
let mut cursor = self.tx.open_ro_cursor(store.db).map_err(StoreError::LmdbError)?;
pub fn iter_from(&self, store: Store, k: K) -> Result<Iter, StoreError> {
let mut cursor = self.tx.open_ro_cursor(store.0).map_err(StoreError::LmdbError)?;
let iter = cursor.iter_from(k);
Ok(Iter {
iter,
@ -154,7 +154,7 @@ where
impl<'env> Iterator for Iter<'env> {
type Item = (&'env [u8], Result<Option<Value<'env>>, StoreError>);
fn next(&mut self) -> Option<(&'env [u8], Result<Option<Value<'env>>, StoreError>)> {
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
None => None,
Some((key, bytes)) => Some((key, read_transform(Ok(bytes)))),
@ -162,17 +162,13 @@ impl<'env> Iterator for Iter<'env> {
}
}
/// Wrapper around an `lmdb::Database`. At this time, the underlying LMDB
/// New type around an `lmdb::Database`. At this time, the underlying LMDB
/// handle (within lmdb-rs::Database) is a C integer, so Copy is automatic.
#[derive(Copy, Clone)]
pub struct Store {
db: Database,
}
pub struct Store(Database);
impl Store {
pub fn new(db: Database) -> Store {
Store {
db,
}
Store(db)
}
}

@ -43,7 +43,7 @@ pub enum Type {
/// We use manual tagging, because <https://github.com/serde-rs/serde/issues/610>.
impl Type {
pub fn from_tag(tag: u8) -> Result<Type, DataError> {
Type::from_primitive(tag).ok_or(DataError::UnknownType(tag))
Type::from_primitive(tag).ok_or_else(|| DataError::UnknownType(tag))
}
pub fn to_tag(self) -> u8 {
@ -108,7 +108,7 @@ pub enum OwnedValue {
Blob(Vec<u8>),
}
fn uuid<'s>(bytes: &'s [u8]) -> Result<Value<'s>, DataError> {
fn uuid(bytes: &[u8]) -> Result<Value, DataError> {
if bytes.len() == 16 {
Ok(Value::Uuid(array_ref![bytes, 0, 16]))
} else {

Loading…
Cancel
Save