From 15ccf07784fd831adbc2a2b29e78e382c4bbae79 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Tue, 16 Jul 2019 14:26:47 +1000 Subject: [PATCH 1/3] refactor value layout for easier additional frameworks --- src/kv/value/internal.rs | 92 +++++++++++++++++++++++++++++----------- src/kv/value/mod.rs | 36 ---------------- 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/src/kv/value/internal.rs b/src/kv/value/internal.rs index 2c4772322..7b7e4cd0b 100644 --- a/src/kv/value/internal.rs +++ b/src/kv/value/internal.rs @@ -1,6 +1,7 @@ use std::fmt; use super::{Fill, Slot, Error}; +use kv; // `Visit` and `Visitor` is an internal API for visiting the structure of a value. // It's not intended to be public (at this stage). @@ -68,41 +69,82 @@ pub(super) enum Primitive<'v> { None, } -/// A visitor for `std::fmt`. -pub(super) struct FmtVisitor<'a, 'b: 'a>(pub(super) &'a mut fmt::Formatter<'b>); - -impl<'a, 'b: 'a> Visitor for FmtVisitor<'a, 'b> { - fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error> { - v.fmt(self.0)?; +mod fmt_support { + use super::*; + + impl<'v> kv::Value<'v> { + /// Get a value from a debuggable type. + pub fn from_debug(value: &'v T) -> Self + where + T: fmt::Debug, + { + kv::Value { + inner: Inner::Debug(value), + } + } - Ok(()) + /// Get a value from a displayable type. + pub fn from_display(value: &'v T) -> Self + where + T: fmt::Display, + { + kv::Value { + inner: Inner::Display(value), + } + } } - fn u64(&mut self, v: u64) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) - } + impl<'v> fmt::Debug for kv::Value<'v> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.visit(&mut FmtVisitor(f))?; - fn i64(&mut self, v: i64) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) + Ok(()) + } } - fn f64(&mut self, v: f64) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) - } + impl<'v> fmt::Display for kv::Value<'v> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.visit(&mut FmtVisitor(f))?; - fn bool(&mut self, v: bool) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) + Ok(()) + } } + + struct FmtVisitor<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>); - fn char(&mut self, v: char) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) - } + impl<'a, 'b: 'a> Visitor for FmtVisitor<'a, 'b> { + fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error> { + v.fmt(self.0)?; - fn str(&mut self, v: &str) -> Result<(), Error> { - self.debug(&format_args!("{:?}", v)) - } + Ok(()) + } + + fn u64(&mut self, v: u64) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } - fn none(&mut self) -> Result<(), Error> { - self.debug(&format_args!("None")) + fn i64(&mut self, v: i64) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } + + fn f64(&mut self, v: f64) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } + + fn bool(&mut self, v: bool) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } + + fn char(&mut self, v: char) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } + + fn str(&mut self, v: &str) -> Result<(), Error> { + self.debug(&format_args!("{:?}", v)) + } + + fn none(&mut self) -> Result<(), Error> { + self.debug(&format_args!("None")) + } } } diff --git a/src/kv/value/mod.rs b/src/kv/value/mod.rs index 1053589e5..59625ea3a 100644 --- a/src/kv/value/mod.rs +++ b/src/kv/value/mod.rs @@ -102,26 +102,6 @@ impl<'v> Value<'v> { } } - /// Get a value from a debuggable type. - pub fn from_debug(value: &'v T) -> Self - where - T: fmt::Debug, - { - Value { - inner: Inner::Debug(value), - } - } - - /// Get a value from a displayable type. - pub fn from_display(value: &'v T) -> Self - where - T: fmt::Display, - { - Value { - inner: Inner::Display(value), - } - } - /// Get a value from a fillable slot. pub fn from_fill(value: &'v T) -> Self where @@ -137,22 +117,6 @@ impl<'v> Value<'v> { } } -impl<'v> fmt::Debug for Value<'v> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.visit(&mut self::internal::FmtVisitor(f))?; - - Ok(()) - } -} - -impl<'v> fmt::Display for Value<'v> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.visit(&mut self::internal::FmtVisitor(f))?; - - Ok(()) - } -} - #[cfg(test)] mod tests { use super::*; From 06beb05c422e077e51b1f7a1c7b05f01a16885f6 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Tue, 16 Jul 2019 14:29:08 +1000 Subject: [PATCH 2/3] add sval support for Value bump to 1.31.0 --- .travis.yml | 2 +- Cargo.toml | 6 ++- src/kv/value/internal.rs | 88 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a87b92b19..baeb980a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ rust: - nightly matrix: include: - - rust: 1.21.0 + - rust: 1.31.0 script: - cargo test --verbose --features kv_unstable - cargo test --verbose --features "kv_unstable std" diff --git a/Cargo.toml b/Cargo.toml index 0e4c79998..727edfb18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ exclude = ["rfcs/**/*", "/.travis.yml", "/appveyor.yml"] build = "build.rs" [package.metadata.docs.rs] -features = ["std", "serde", "kv_unstable"] +features = ["std", "serde", "kv_unstable_sval"] [[test]] name = "filters" @@ -39,8 +39,9 @@ release_max_level_trace = [] std = [] -# requires Rust `>= 1.21.0` +# requires Rust `>= 1.31.0` kv_unstable = [] +kv_unstable_sval = ["kv_unstable", "sval/fmt"] [badges] travis-ci = { repository = "rust-lang-nursery/log" } @@ -49,6 +50,7 @@ appveyor = { repository = "alexcrichton/log" } [dependencies] cfg-if = "0.1.2" serde = { version = "1.0", optional = true, default-features = false } +sval = { version = "0.4.2", optional = true, default-features = false } [dev-dependencies] serde_test = "1.0" diff --git a/src/kv/value/internal.rs b/src/kv/value/internal.rs index 7b7e4cd0b..5612cf633 100644 --- a/src/kv/value/internal.rs +++ b/src/kv/value/internal.rs @@ -21,6 +21,10 @@ pub(super) enum Inner<'v> { Debug(&'v fmt::Debug), /// A displayable value. Display(&'v fmt::Display), + + #[cfg(feature = "kv_unstable_sval")] + /// A structured value from `sval`. + Sval(&'v sval_support::Value), } impl<'v> Inner<'v> { @@ -38,6 +42,9 @@ impl<'v> Inner<'v> { Inner::Fill(value) => value.fill(&mut Slot::new(visitor)), Inner::Debug(value) => visitor.debug(value), Inner::Display(value) => visitor.display(value), + + #[cfg(feature = "kv_unstable_sval")] + Inner::Sval(value) => visitor.sval(value), } } } @@ -56,6 +63,9 @@ pub(super) trait Visitor { fn char(&mut self, v: char) -> Result<(), Error>; fn str(&mut self, v: &str) -> Result<(), Error>; fn none(&mut self) -> Result<(), Error>; + + #[cfg(feature = "kv_unstable_sval")] + fn sval(&mut self, v: &sval_support::Value) -> Result<(), Error>; } #[derive(Clone, Copy)] @@ -146,5 +156,83 @@ mod fmt_support { fn none(&mut self) -> Result<(), Error> { self.debug(&format_args!("None")) } + + #[cfg(feature = "kv_unstable_sval")] + fn sval(&mut self, v: &sval_support::Value) -> Result<(), Error> { + sval_support::fmt(self.0, v) + } + } +} + +#[cfg(feature = "kv_unstable_sval")] +mod sval_support { + use super::*; + + extern crate sval; + + impl<'v> kv::Value<'v> { + /// Get a value from a structured type. + pub fn from_sval(value: &'v T) -> Self + where + T: sval::Value, + { + kv::Value { + inner: Inner::Sval(value), + } + } + } + + impl<'v> sval::Value for kv::Value<'v> { + fn stream(&self, s: &mut sval::value::Stream) -> sval::value::Result { + self.visit(&mut SvalVisitor(s)).map_err(|_| sval::value::Error::msg("sval formatting failed"))?; + + Ok(()) + } + } + + pub(super) use self::sval::Value; + + pub(super) fn fmt(f: &mut fmt::Formatter, v: &sval::Value) -> Result<(), Error> { + sval::fmt::debug(f, v).map_err(|_| Error::msg("sval formatting failed")) + } + + struct SvalVisitor<'a, 'b: 'a>(&'a mut sval::value::Stream<'b>); + + impl<'a, 'b: 'a> Visitor for SvalVisitor<'a, 'b> { + fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error> { + self.0.fmt(format_args!("{:?}", v)).map_err(|_| Error::msg("sval formatting failed")) + } + + fn u64(&mut self, v: u64) -> Result<(), Error> { + self.0.u64(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn i64(&mut self, v: i64) -> Result<(), Error> { + self.0.i64(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn f64(&mut self, v: f64) -> Result<(), Error> { + self.0.f64(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn bool(&mut self, v: bool) -> Result<(), Error> { + self.0.bool(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn char(&mut self, v: char) -> Result<(), Error> { + self.0.char(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn str(&mut self, v: &str) -> Result<(), Error> { + self.0.str(v).map_err(|_| Error::msg("sval formatting failed")) + } + + fn none(&mut self) -> Result<(), Error> { + self.0.none().map_err(|_| Error::msg("sval formatting failed")) + } + + fn sval(&mut self, v: &sval::Value) -> Result<(), Error> { + self.0.any(v).map_err(|_| Error::msg("sval formatting failed")) + } } } From 368a7777dc6d379d54d195b8e288d5023b474a9b Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Tue, 16 Jul 2019 15:21:36 +1000 Subject: [PATCH 3/3] test sval feature in CI split consumer builds of MSRV from dev builds --- .travis.yml | 20 +++++--- Cargo.toml | 4 +- src/kv/error.rs | 32 +++++++----- src/kv/value/impls.rs | 20 ++++---- src/kv/value/internal.rs | 62 ++++++++++++++++------- src/kv/value/mod.rs | 4 +- src/kv/value/test.rs | 107 +++++---------------------------------- src/lib.rs | 4 +- 8 files changed, 105 insertions(+), 148 deletions(-) diff --git a/.travis.yml b/.travis.yml index baeb980a4..4fd7e9195 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,31 @@ language: rust sudo: false rust: - - 1.16.0 - stable - beta - nightly matrix: include: - - rust: 1.31.0 - script: - - cargo test --verbose --features kv_unstable - - cargo test --verbose --features "kv_unstable std" - rust: stable + env: + - LABEL="Embedded" script: - rustup target add thumbv6m-none-eabi - cargo build --verbose --target=thumbv6m-none-eabi + - rust: 1.16.0 + env: + - LABEL="MSRV" + script: + - cargo build --verbose + - cargo build --verbose --features serde + - cargo build --verbose --features std script: - - cargo build --verbose - - cargo build --verbose --features serde - - cargo build --verbose --features std - cargo test --verbose - cargo test --verbose --features serde - cargo test --verbose --features std + - cargo test --verbose --features kv_unstable + - cargo test --verbose --features "kv_unstable std" + - cargo test --verbose --features "kv_unstable_sval" - cargo run --verbose --manifest-path test_max_level_features/Cargo.toml - cargo run --verbose --manifest-path test_max_level_features/Cargo.toml --release diff --git a/Cargo.toml b/Cargo.toml index 727edfb18..8be3d5047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,8 @@ release_max_level_trace = [] std = [] -# requires Rust `>= 1.31.0` +# requires the latest stable +# this will have a tighter MSRV before stabilization kv_unstable = [] kv_unstable_sval = ["kv_unstable", "sval/fmt"] @@ -54,3 +55,4 @@ sval = { version = "0.4.2", optional = true, default-features = false } [dev-dependencies] serde_test = "1.0" +sval = { version = "0.4.2", features = ["test"] } diff --git a/src/kv/error.rs b/src/kv/error.rs index b6ecb47a7..0f5652f92 100644 --- a/src/kv/error.rs +++ b/src/kv/error.rs @@ -1,6 +1,4 @@ use std::fmt; -#[cfg(feature = "std")] -use std::io; /// An error encountered while working with structured data. #[derive(Debug)] @@ -11,13 +9,13 @@ pub struct Error { #[derive(Debug)] enum Inner { #[cfg(feature = "std")] - Io(io::Error), + Boxed(std_support::BoxedError), Msg(&'static str), Fmt, } impl Error { - /// Create an error from the given message. + /// Create an error from a message. pub fn msg(msg: &'static str) -> Self { Error { inner: Inner::Msg(msg), @@ -30,7 +28,7 @@ impl fmt::Display for Error { use self::Inner::*; match &self.inner { #[cfg(feature = "std")] - &Io(ref err) => err.fmt(f), + &Boxed(ref err) => err.fmt(f), &Msg(ref msg) => msg.fmt(f), &Fmt => fmt::Error.fmt(f), } @@ -56,6 +54,20 @@ mod std_support { use super::*; use std::{error, io}; + pub(super) type BoxedError = Box; + + impl Error { + /// Create an error from a standard error type. + pub fn boxed(err: E) -> Self + where + E: Into, + { + Error { + inner: Inner::Boxed(err.into()) + } + } + } + impl error::Error for Error { fn description(&self) -> &str { "key values error" @@ -64,19 +76,13 @@ mod std_support { impl From for Error { fn from(err: io::Error) -> Self { - Error { - inner: Inner::Io(err) - } + Error::boxed(err) } } impl From for io::Error { fn from(err: Error) -> Self { - if let Inner::Io(err) = err.inner { - err - } else { - io::Error::new(io::ErrorKind::Other, err) - } + io::Error::new(io::ErrorKind::Other, err) } } } diff --git a/src/kv/value/impls.rs b/src/kv/value/impls.rs index 7e42b3468..ea181466b 100644 --- a/src/kv/value/impls.rs +++ b/src/kv/value/impls.rs @@ -241,16 +241,16 @@ mod tests { #[test] fn test_to_value_display() { - assert_eq!(42u64.to_value().to_str_buf(), "42"); - assert_eq!(42i64.to_value().to_str_buf(), "42"); - assert_eq!(42.01f64.to_value().to_str_buf(), "42.01"); - assert_eq!(true.to_value().to_str_buf(), "true"); - assert_eq!('a'.to_value().to_str_buf(), "'a'"); - assert_eq!(format_args!("a {}", "value").to_value().to_str_buf(), "a value"); - assert_eq!("a loong string".to_value().to_str_buf(), "\"a loong string\""); - assert_eq!(Some(true).to_value().to_str_buf(), "true"); - assert_eq!(().to_value().to_str_buf(), "None"); - assert_eq!(Option::None::.to_value().to_str_buf(), "None"); + assert_eq!(42u64.to_value().to_string(), "42"); + assert_eq!(42i64.to_value().to_string(), "42"); + assert_eq!(42.01f64.to_value().to_string(), "42.01"); + assert_eq!(true.to_value().to_string(), "true"); + assert_eq!('a'.to_value().to_string(), "'a'"); + assert_eq!(format_args!("a {}", "value").to_value().to_string(), "a value"); + assert_eq!("a loong string".to_value().to_string(), "\"a loong string\""); + assert_eq!(Some(true).to_value().to_string(), "true"); + assert_eq!(().to_value().to_string(), "None"); + assert_eq!(Option::None::.to_value().to_string(), "None"); } #[test] diff --git a/src/kv/value/internal.rs b/src/kv/value/internal.rs index 5612cf633..5f01a317b 100644 --- a/src/kv/value/internal.rs +++ b/src/kv/value/internal.rs @@ -3,12 +3,8 @@ use std::fmt; use super::{Fill, Slot, Error}; use kv; -// `Visit` and `Visitor` is an internal API for visiting the structure of a value. +// `Visitor` is an internal API for visiting the structure of a value. // It's not intended to be public (at this stage). -// -// Right now we only have an implementation for `std::fmt`, but -// this trait makes it possible to add more structured backends like -// `serde` that can retain that original structure. /// A container for a structured value for a specific kind of visitor. #[derive(Clone, Copy)] @@ -165,7 +161,7 @@ mod fmt_support { } #[cfg(feature = "kv_unstable_sval")] -mod sval_support { +pub(super) mod sval_support { use super::*; extern crate sval; @@ -184,55 +180,85 @@ mod sval_support { impl<'v> sval::Value for kv::Value<'v> { fn stream(&self, s: &mut sval::value::Stream) -> sval::value::Result { - self.visit(&mut SvalVisitor(s)).map_err(|_| sval::value::Error::msg("sval formatting failed"))?; + self.visit(&mut SvalVisitor(s)).map_err(Error::into_sval)?; Ok(()) } } - pub(super) use self::sval::Value; + pub(in kv::value) use self::sval::Value; pub(super) fn fmt(f: &mut fmt::Formatter, v: &sval::Value) -> Result<(), Error> { - sval::fmt::debug(f, v).map_err(|_| Error::msg("sval formatting failed")) + sval::fmt::debug(f, v)?; + Ok(()) + } + + impl Error { + fn from_sval(_: sval::value::Error) -> Self { + Error::msg("`sval` serialization failed") + } + + fn into_sval(self) -> sval::value::Error { + sval::value::Error::msg("`sval` serialization failed") + } } struct SvalVisitor<'a, 'b: 'a>(&'a mut sval::value::Stream<'b>); impl<'a, 'b: 'a> Visitor for SvalVisitor<'a, 'b> { fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error> { - self.0.fmt(format_args!("{:?}", v)).map_err(|_| Error::msg("sval formatting failed")) + self.0.fmt(format_args!("{:?}", v)).map_err(Error::from_sval) } fn u64(&mut self, v: u64) -> Result<(), Error> { - self.0.u64(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.u64(v).map_err(Error::from_sval) } fn i64(&mut self, v: i64) -> Result<(), Error> { - self.0.i64(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.i64(v).map_err(Error::from_sval) } fn f64(&mut self, v: f64) -> Result<(), Error> { - self.0.f64(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.f64(v).map_err(Error::from_sval) } fn bool(&mut self, v: bool) -> Result<(), Error> { - self.0.bool(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.bool(v).map_err(Error::from_sval) } fn char(&mut self, v: char) -> Result<(), Error> { - self.0.char(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.char(v).map_err(Error::from_sval) } fn str(&mut self, v: &str) -> Result<(), Error> { - self.0.str(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.str(v).map_err(Error::from_sval) } fn none(&mut self) -> Result<(), Error> { - self.0.none().map_err(|_| Error::msg("sval formatting failed")) + self.0.none().map_err(Error::from_sval) } fn sval(&mut self, v: &sval::Value) -> Result<(), Error> { - self.0.any(v).map_err(|_| Error::msg("sval formatting failed")) + self.0.any(v).map_err(Error::from_sval) + } + } + + #[cfg(test)] + mod tests { + use super::*; + use kv::value::test::Token; + + #[test] + fn test_from_sval() { + assert_eq!(kv::Value::from_sval(&42u64).to_token(), Token::Sval); + } + + #[test] + fn test_sval_structured() { + let value = kv::Value::from(42u64); + let expected = vec![sval::test::Token::Unsigned(42)]; + + assert_eq!(sval::test::tokens(value), expected); } } } diff --git a/src/kv/value/mod.rs b/src/kv/value/mod.rs index 59625ea3a..1695afbd1 100644 --- a/src/kv/value/mod.rs +++ b/src/kv/value/mod.rs @@ -133,7 +133,7 @@ mod tests { } } - assert_eq!("1", Value::from_fill(&TestFill).to_str_buf()); + assert_eq!("1", Value::from_fill(&TestFill).to_string()); } #[test] @@ -150,6 +150,6 @@ mod tests { } } - let _ = Value::from_fill(&BadFill).to_str_buf(); + let _ = Value::from_fill(&BadFill).to_string(); } } diff --git a/src/kv/value/test.rs b/src/kv/value/test.rs index 0d5239bcc..c9c03dc42 100644 --- a/src/kv/value/test.rs +++ b/src/kv/value/test.rs @@ -1,10 +1,10 @@ // Test support for inspecting Values -use std::fmt::{self, Write}; +use std::fmt; use std::str; use super::{Value, Error}; -use super::internal::Visitor; +use super::internal; #[derive(Debug, PartialEq)] pub(in kv) enum Token { @@ -13,47 +13,11 @@ pub(in kv) enum Token { F64(f64), Char(char), Bool(bool), - Str(StrBuf), + Str(String), None, -} - -#[derive(Debug, PartialEq)] -pub(in kv) struct StrBuf { - buf: [u8; 16], - len: usize, -} - -impl<'a> From<&'a str> for StrBuf { - fn from(s: &'a str) -> Self { - let mut buf = Buffer::new(); - write!(&mut buf, "{}", s).unwrap(); - buf.into_str_buf() - } -} - -impl PartialEq for StrBuf { - fn eq(&self, other: &str) -> bool { - self.as_ref() == other - } -} - -impl<'a> PartialEq<&'a str> for StrBuf { - fn eq(&self, other: &&'a str) -> bool { - self.as_ref() == *other - } -} - -impl<'a> PartialEq for &'a str { - fn eq(&self, other: &StrBuf) -> bool { - *self == other.as_ref() - } -} - -impl AsRef for StrBuf { - fn as_ref(&self) -> &str { - str::from_utf8(&self.buf[0..self.len]).unwrap() - } + #[cfg(feature = "kv_unstable_sval")] + Sval, } #[cfg(test)] @@ -61,12 +25,9 @@ impl<'v> Value<'v> { pub(in kv) fn to_token(&self) -> Token { struct TestVisitor(Option); - impl Visitor for TestVisitor { + impl internal::Visitor for TestVisitor { fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error> { - let mut buf = Buffer::new(); - write!(&mut buf, "{:?}", v)?; - - self.0 = Some(Token::Str(buf.into_str_buf())); + self.0 = Some(Token::Str(format!("{:?}", v))); Ok(()) } @@ -104,6 +65,12 @@ impl<'v> Value<'v> { self.0 = Some(Token::None); Ok(()) } + + #[cfg(feature = "kv_unstable_sval")] + fn sval(&mut self, _: &internal::sval_support::Value) -> Result<(), Error> { + self.0 = Some(Token::Sval); + Ok(()) + } } let mut visitor = TestVisitor(None); @@ -111,52 +78,4 @@ impl<'v> Value<'v> { visitor.0.unwrap() } - - pub(in kv) fn to_str_buf(&self) -> StrBuf { - let mut buf = Buffer::new(); - write!(&mut buf, "{}", self).unwrap(); - - buf.into_str_buf() - } -} - -// A quick-and-dirty no-std buffer -// to write strings into -struct Buffer { - buf: [u8; 16], - len: usize, -} - -impl Buffer { - fn new() -> Self { - Buffer { - buf: [0; 16], - len: 0, - } - } - - fn into_str_buf(self) -> StrBuf { - StrBuf { - buf: self.buf, - len: self.len, - } - } -} - -impl Write for Buffer { - fn write_str(&mut self, s: &str) -> fmt::Result { - let bytes = s.as_bytes(); - - let end = self.len + bytes.len(); - - if end > 16 { - panic!("`{}` would overflow", s); - } - - let buf = &mut self.buf[self.len..end]; - buf.copy_from_slice(bytes); - self.len = end; - - Ok(()) - } } diff --git a/src/lib.rs b/src/lib.rs index c95837d74..ba35c3c43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,13 +271,13 @@ )] #![warn(missing_docs)] #![deny(missing_debug_implementations)] -#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] // When compiled for the rustc compiler itself we want to make sure that this is // an unstable crate #![cfg_attr(rustbuild, feature(staged_api, rustc_private))] #![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] -#[cfg(not(feature = "std"))] +#[cfg(all(not(feature = "std"), not(test)))] extern crate core as std; #[macro_use]