Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use stable internals for key-value API #550

Merged
merged 7 commits into from Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Expand Up @@ -129,9 +129,6 @@ jobs:
run: |
rustup update 1.31.0 --no-self-update
rustup default 1.31.0
- run: cargo build --verbose
- run: cargo build --verbose --features serde
- run: cargo build --verbose --features std
- run: cargo test --verbose --manifest-path tests/Cargo.toml

embedded:
Expand Down
12 changes: 7 additions & 5 deletions Cargo.toml
Expand Up @@ -48,18 +48,20 @@ std = []
# requires the latest stable
# this will have a tighter MSRV before stabilization
kv_unstable = ["value-bag"]
kv_unstable_sval = ["kv_unstable", "value-bag/sval", "sval"]
kv_unstable_sval = ["kv_unstable", "value-bag/sval", "sval", "sval_ref"]
kv_unstable_std = ["std", "kv_unstable", "value-bag/error"]
kv_unstable_serde = ["kv_unstable_std", "value-bag/serde", "serde"]

[dependencies]
serde = { version = "1.0", optional = true, default-features = false }
sval = { version = "=1.0.0-alpha.5", optional = true, default-features = false }
value-bag = { version = "=1.0.0-alpha.9", optional = true, default-features = false }
sval = { version = "2.1", optional = true, default-features = false }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up skipping a stable 1.x for this library in the end, because the API changed fairly significantly between beta releases.

sval_ref = { version = "2.1", optional = true, default-features = false }
value-bag = { version = "1.1", optional = true, default-features = false }

[dev-dependencies]
rustversion = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_test = "1.0"
sval = { version = "=1.0.0-alpha.5", features = ["derive"] }
value-bag = { version = "=1.0.0-alpha.9", features = ["test"] }
sval = { version = "2.1" }
sval_derive = { version = "2.1" }
value-bag = { version = "1.1", features = ["test"] }
24 changes: 22 additions & 2 deletions src/kv/key.rs
Expand Up @@ -48,6 +48,12 @@ impl<'k> Key<'k> {
pub fn as_str(&self) -> &str {
self.key
}

/// Try get a string borrowed for the `'k` lifetime from this key.
pub fn to_borrowed_str(&self) -> Option<&'k str> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns an Option even though it's currently always Some so that we've got room to make the internals something like a Cow<'k, str>.

// NOTE: This API leaves room for keys to be owned
Some(self.key)
}
}

impl<'k> fmt::Display for Key<'k> {
Expand Down Expand Up @@ -98,11 +104,25 @@ mod sval_support {
use super::*;

extern crate sval;
extern crate sval_ref;

use self::sval::value::{self, Value};
use self::sval::Value;
use self::sval_ref::ValueRef;

impl<'a> Value for Key<'a> {
fn stream(&self, stream: &mut value::Stream) -> value::Result {
fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(
&'sval self,
stream: &mut S,
) -> sval::Result {
self.key.stream(stream)
}
}

impl<'a> ValueRef<'a> for Key<'a> {
fn stream_ref<S: self::sval::Stream<'a> + ?Sized>(
&self,
stream: &mut S,
) -> self::sval::Result {
self.key.stream(stream)
}
}
Expand Down
72 changes: 47 additions & 25 deletions src/kv/source.rs
Expand Up @@ -2,6 +2,8 @@

#[cfg(feature = "kv_unstable_sval")]
extern crate sval;
#[cfg(feature = "kv_unstable_sval")]
extern crate sval_ref;

#[cfg(feature = "kv_unstable_serde")]
extern crate serde;
Expand Down Expand Up @@ -460,74 +462,94 @@ where
mod sval_support {
use super::*;

use self::sval::value;

impl<S> value::Value for AsMap<S>
impl<S> self::sval::Value for AsMap<S>
where
S: Source,
{
fn stream(&self, stream: &mut value::Stream) -> value::Result {
struct StreamVisitor<'a, 'b>(&'a mut value::Stream<'b>);
fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>(
&'sval self,
stream: &mut SV,
) -> self::sval::Result {
struct StreamVisitor<'a, V: ?Sized>(&'a mut V);

impl<'a, 'b, 'kvs> Visitor<'kvs> for StreamVisitor<'a, 'b> {
impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> {
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
self.0
.map_key(key)
.map_key_begin()
.map_err(|_| Error::msg("failed to stream map key"))?;
sval_ref::stream_ref(self.0, key)
.map_err(|_| Error::msg("failed to stream map key"))?;
self.0
.map_key_end()
.map_err(|_| Error::msg("failed to stream map key"))?;

self.0
.map_value(value)
.map_value_begin()
.map_err(|_| Error::msg("failed to stream map value"))?;
sval_ref::stream_ref(self.0, value)
.map_err(|_| Error::msg("failed to stream map value"))?;
self.0
.map_value_end()
.map_err(|_| Error::msg("failed to stream map value"))?;

Ok(())
}
}

stream
.map_begin(Some(self.count()))
.map_err(|_| self::sval::Error::msg("failed to begin map"))?;
.map_err(|_| self::sval::Error::new())?;

self.visit(&mut StreamVisitor(stream))
.map_err(|_| self::sval::Error::msg("failed to visit key-values"))?;
.map_err(|_| self::sval::Error::new())?;

stream
.map_end()
.map_err(|_| self::sval::Error::msg("failed to end map"))
stream.map_end().map_err(|_| self::sval::Error::new())
}
}

impl<S> value::Value for AsList<S>
impl<S> self::sval::Value for AsList<S>
where
S: Source,
{
fn stream(&self, stream: &mut value::Stream) -> value::Result {
struct StreamVisitor<'a, 'b>(&'a mut value::Stream<'b>);
fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>(
&'sval self,
stream: &mut SV,
) -> self::sval::Result {
struct StreamVisitor<'a, V: ?Sized>(&'a mut V);

impl<'a, 'b, 'kvs> Visitor<'kvs> for StreamVisitor<'a, 'b> {
impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> {
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
self.0
.seq_elem((key, value))
.map_err(|_| Error::msg("failed to stream seq entry"))?;
.seq_value_begin()
.map_err(|_| Error::msg("failed to stream seq value"))?;
self::sval_ref::stream_ref(self.0, (key, value))
.map_err(|_| Error::msg("failed to stream seq value"))?;
self.0
.seq_value_end()
.map_err(|_| Error::msg("failed to stream seq value"))?;

Ok(())
}
}

stream
.seq_begin(Some(self.count()))
.map_err(|_| self::sval::Error::msg("failed to begin seq"))?;
.map_err(|_| self::sval::Error::new())?;

self.visit(&mut StreamVisitor(stream))
.map_err(|_| self::sval::Error::msg("failed to visit key-values"))?;
.map_err(|_| self::sval::Error::new())?;

stream
.seq_end()
.map_err(|_| self::sval::Error::msg("failed to end seq"))
stream.seq_end().map_err(|_| self::sval::Error::new())
}
}

#[cfg(test)]
mod tests {
extern crate sval_derive;

use super::*;

use self::sval::Value;
use self::sval_derive::Value;

use crate::kv::source;

Expand Down
43 changes: 20 additions & 23 deletions src/kv/value.rs
Expand Up @@ -6,6 +6,8 @@ extern crate value_bag;

#[cfg(feature = "kv_unstable_sval")]
extern crate sval;
#[cfg(feature = "kv_unstable_sval")]
extern crate sval_ref;

#[cfg(feature = "kv_unstable_serde")]
extern crate serde;
Expand Down Expand Up @@ -71,7 +73,7 @@ macro_rules! as_serde {
};
}

/// Get a value from a type implementing `sval::value::Value`.
/// Get a value from a type implementing `sval::Value`.
#[cfg(feature = "kv_unstable_sval")]
#[macro_export]
macro_rules! as_sval {
Expand Down Expand Up @@ -204,14 +206,14 @@ impl<'v> Value<'v> {
}
}

/// Get a value from a type implementing `sval::value::Value`.
/// Get a value from a type implementing `sval::Value`.
#[cfg(feature = "kv_unstable_sval")]
pub fn capture_sval<T>(value: &'v T) -> Self
where
T: self::sval::value::Value + 'static,
T: self::sval::Value + 'static,
{
Value {
inner: ValueBag::capture_sval1(value),
inner: ValueBag::capture_sval2(value),
}
}

Expand Down Expand Up @@ -246,14 +248,14 @@ impl<'v> Value<'v> {
}
}

/// Get a value from a type implementing `sval::value::Value`.
/// Get a value from a type implementing `sval::Value`.
#[cfg(feature = "kv_unstable_sval")]
pub fn from_sval<T>(value: &'v T) -> Self
where
T: self::sval::value::Value,
T: self::sval::Value,
{
Value {
inner: ValueBag::from_sval1(value),
inner: ValueBag::from_sval2(value),
}
}

Expand All @@ -279,14 +281,6 @@ impl<'v> Value<'v> {
}
}

/// Get a value from a type implementing `sval::value::Value`.
#[cfg(feature = "kv_unstable_sval")]
pub fn from_dyn_sval(value: &'v dyn self::sval::value::Value) -> Self {
Value {
inner: ValueBag::from_dyn_sval1(value),
}
}

/// Get a value from an internal primitive.
fn from_value_bag<T>(value: T) -> Self
where
Expand Down Expand Up @@ -422,16 +416,19 @@ impl<'v> self::serde::Serialize for Value<'v> {
}

#[cfg(feature = "kv_unstable_sval")]
impl<'v> self::sval::value::Value for Value<'v> {
fn stream(&self, stream: &mut self::sval::value::Stream) -> self::sval::value::Result {
self::sval::value::Value::stream(&self.inner, stream)
impl<'v> self::sval::Value for Value<'v> {
fn stream<'sval, S: self::sval::Stream<'sval> + ?Sized>(
&'sval self,
stream: &mut S,
) -> self::sval::Result {
self::sval::Value::stream(&self.inner, stream)
}
}

#[cfg(feature = "kv_unstable_sval")]
impl ToValue for dyn self::sval::value::Value {
fn to_value(&self) -> Value {
Value::from_dyn_sval(self)
impl<'v> self::sval_ref::ValueRef<'v> for Value<'v> {
fn stream_ref<S: self::sval::Stream<'v> + ?Sized>(&self, stream: &mut S) -> self::sval::Result {
self::sval_ref::ValueRef::stream_ref(&self.inner, stream)
}
}

Expand Down Expand Up @@ -777,11 +774,11 @@ where
pub(crate) mod tests {
use super::*;

pub(crate) use super::value_bag::test::Token;
pub(crate) use super::value_bag::test::TestToken as Token;

impl<'v> Value<'v> {
pub(crate) fn to_token(&self) -> Token {
self.inner.to_token()
self.inner.to_test_token()
}
}

Expand Down