Skip to content

Commit

Permalink
KeyVisitor::visit_other()
Browse files Browse the repository at this point in the history
Refs #314
  • Loading branch information
ecton committed Feb 2, 2024
1 parent 75ba162 commit b9362a2
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `bonsaidb::client::Error` now implements
`From<bonsaidb::client::ApiError<Infallible>>`.
- `KeyVisitor::visit_other` is a new function that indicates the key encoded is
a byte sequence of a known type.

### Fixed

Expand All @@ -32,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Entry`
- `EntryInsert`
- `EntryUpdate`
- `KeyDescriber` no longer panics when a `Key` type calls no visitor methods in
its `KeyEncoding::describe` implementation.

## v0.5.0

Expand Down
64 changes: 59 additions & 5 deletions crates/bonsaidb-core/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod varint;

mod deprecated;

use std::any::type_name;
use std::borrow::{Borrow, Cow};
use std::collections::HashMap;
use std::convert::Infallible;
Expand Down Expand Up @@ -244,6 +245,10 @@ pub trait KeyVisitor {
/// Report that a basic key type is encoded next in this key.
fn visit_type(&mut self, kind: KeyKind);

/// Report that a custom type is encoded next as a single byte sequence in
/// this key.
fn visit_other(&mut self, kind: impl Into<Cow<'static, str>>);

/// Report that a composite type made up of `count` fields is encoded next in
/// this key.
///
Expand Down Expand Up @@ -411,12 +416,10 @@ impl KeyDescription {
/// This function will panic if `KE` emits an imbalanced sequence of visit
/// calls.
#[must_use]
pub fn for_encoding<KE: KeyEncoding<K>, K: for<'k> Key<'k>>() -> Self {
pub fn for_encoding<KE: KeyEncoding<K>, K: for<'k> Key<'k> + 'static>() -> Self {
let mut describer = KeyDescriber::default();
KE::describe(&mut describer);
describer
.result
.expect("invalid KeyEncoding::describe implementation -- imbalanced visit calls")
describer.finish_for::<K>()
}

/// Returns the description of a given [`Key`] implementor.
Expand All @@ -426,7 +429,7 @@ impl KeyDescription {
/// This function will panic if `KE` emits an imbalanced sequence of visit
/// calls.
#[must_use]
pub fn for_key<K: for<'k> Key<'k>>() -> Self {
pub fn for_key<K: for<'k> Key<'k> + 'static>() -> Self {
Self::for_encoding::<K, K>()
}
}
Expand Down Expand Up @@ -465,6 +468,18 @@ impl KeyDescriber {
}
}
}

fn finish_for<T>(self) -> KeyDescription
where
T: 'static,
{
assert!(
self.stack.is_empty(),
"invalid KeyEncoding::describe implementation -- imbalanced visit calls"
);
self.result
.unwrap_or_else(|| KeyDescription::Other(Cow::Borrowed(type_name::<T>())))
}
}

impl KeyVisitor for KeyDescriber {
Expand All @@ -473,6 +488,10 @@ impl KeyVisitor for KeyDescriber {
self.record(description);
}

fn visit_other(&mut self, kind: impl Into<Cow<'static, str>>) {
self.record(KeyDescription::Other(kind.into()));
}

fn visit_composite(&mut self, kind: CompositeKind, count: usize) {
self.stack.push(CompositeKeyDescription {
kind,
Expand Down Expand Up @@ -2759,6 +2778,34 @@ fn enum_derive_tests() -> anyhow::Result<()> {
#[test]
fn key_descriptions() {
use time::limited::TimeEpoch;

#[derive(Clone)]
struct NoDescriptionKey;

impl<'k> Key<'k> for NoDescriptionKey {
const CAN_OWN_BYTES: bool = false;

fn from_ord_bytes<'e>(_bytes: ByteSource<'k, 'e>) -> Result<Self, Self::Error> {
Ok(NoDescriptionKey)
}
}

impl KeyEncoding<NoDescriptionKey> for NoDescriptionKey {
type Error = Infallible;

const LENGTH: Option<usize> = None;

fn describe<Visitor>(_visitor: &mut Visitor)
where
Visitor: KeyVisitor,
{
}

fn as_ord_bytes(&self) -> Result<Cow<'_, [u8]>, Self::Error> {
Ok(Cow::Borrowed(b""))
}
}

assert_eq!(
KeyDescription::for_key::<Vec<u8>>(),
KeyDescription::Basic(KeyKind::Bytes)
Expand Down Expand Up @@ -2790,6 +2837,13 @@ fn key_descriptions() {
attributes: HashMap::new(),
})
);

assert_eq!(
KeyDescription::for_key::<NoDescriptionKey>(),
KeyDescription::Other(Cow::Borrowed(
"bonsaidb_core::key::key_descriptions::NoDescriptionKey"
))
);
}

#[test]
Expand Down

0 comments on commit b9362a2

Please sign in to comment.