From fc150a2cebedb30e05f47f078db3dcffceb4be98 Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Sun, 5 Nov 2023 10:42:49 -0800 Subject: [PATCH] Implement RedbKey and RedbValue for bool --- src/types.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++ tests/basic_tests.rs | 27 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/types.rs b/src/types.rs index 19312dfc..01f334ec 100644 --- a/src/types.rs +++ b/src/types.rs @@ -168,6 +168,53 @@ impl RedbKey for () { } } +impl RedbValue for bool { + type SelfType<'a> = bool + where + Self: 'a; + type AsBytes<'a> = &'a [u8] + where + Self: 'a; + + fn fixed_width() -> Option { + Some(1) + } + + fn from_bytes<'a>(data: &'a [u8]) -> bool + where + Self: 'a, + { + match data[0] { + 0 => false, + 1 => true, + _ => unreachable!(), + } + } + + fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a [u8] + where + Self: 'a, + Self: 'b, + { + match value { + true => &[1], + false => &[0], + } + } + + fn type_name() -> TypeName { + TypeName::internal("bool") + } +} + +impl RedbKey for bool { + fn compare(data1: &[u8], data2: &[u8]) -> Ordering { + let value1 = Self::from_bytes(data1); + let value2 = Self::from_bytes(data2); + value1.cmp(&value2) + } +} + impl RedbValue for Option { type SelfType<'a> = Option> where diff --git a/tests/basic_tests.rs b/tests/basic_tests.rs index ff9746cb..ee5eb2c7 100644 --- a/tests/basic_tests.rs +++ b/tests/basic_tests.rs @@ -1037,6 +1037,33 @@ fn empty_type() { assert!(!table.is_empty().unwrap()); } +#[test] +#[allow(clippy::bool_assert_comparison)] +fn bool_type() { + let tmpfile = create_tempfile(); + let db = Database::create(tmpfile.path()).unwrap(); + + let definition: TableDefinition = TableDefinition::new("x"); + + let write_txn = db.begin_write().unwrap(); + { + let mut table = write_txn.open_table(definition).unwrap(); + table.insert(true, &false).unwrap(); + table.insert(&false, false).unwrap(); + } + write_txn.commit().unwrap(); + + let read_txn = db.begin_read().unwrap(); + let table = read_txn.open_table(definition).unwrap(); + assert_eq!(false, table.get(&true).unwrap().unwrap().value()); + assert_eq!(false, table.get(&false).unwrap().unwrap().value()); + + let mut iter = table.iter().unwrap(); + assert_eq!(iter.next().unwrap().unwrap().0.value(), false); + assert_eq!(iter.next().unwrap().unwrap().0.value(), true); + assert!(iter.next().is_none()); +} + #[test] fn option_type() { let tmpfile = create_tempfile();