mirror of
https://gitee.com/openharmony/third_party_rust_log
synced 2024-11-27 01:40:27 +00:00
make value internal visitor support borrowing
This commit is contained in:
parent
ddb118e466
commit
6743f4a0d2
@ -24,17 +24,9 @@ pub(super) enum Inner<'v> {
|
||||
}
|
||||
|
||||
impl<'v> Inner<'v> {
|
||||
pub(super) fn visit(&self, visitor: &mut dyn Visitor) -> Result<(), Error> {
|
||||
match *self {
|
||||
Inner::Primitive(value) => match value {
|
||||
Primitive::Signed(value) => visitor.i64(value),
|
||||
Primitive::Unsigned(value) => visitor.u64(value),
|
||||
Primitive::Float(value) => visitor.f64(value),
|
||||
Primitive::Bool(value) => visitor.bool(value),
|
||||
Primitive::Char(value) => visitor.char(value),
|
||||
Primitive::Str(value) => visitor.str(value),
|
||||
Primitive::None => visitor.none(),
|
||||
},
|
||||
pub(super) fn visit(self, visitor: &mut dyn Visitor<'v>) -> Result<(), Error> {
|
||||
match self {
|
||||
Inner::Primitive(value) => value.visit(visitor),
|
||||
Inner::Fill(value) => value.fill(&mut Slot::new(visitor)),
|
||||
Inner::Debug(value) => visitor.debug(value),
|
||||
Inner::Display(value) => visitor.display(value),
|
||||
@ -46,7 +38,7 @@ impl<'v> Inner<'v> {
|
||||
}
|
||||
|
||||
/// The internal serialization contract.
|
||||
pub(super) trait Visitor {
|
||||
pub(super) trait Visitor<'v> {
|
||||
fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error>;
|
||||
fn display(&mut self, v: &dyn fmt::Display) -> Result<(), Error> {
|
||||
self.debug(&format_args!("{}", v))
|
||||
@ -57,7 +49,12 @@ pub(super) trait Visitor {
|
||||
fn f64(&mut self, v: f64) -> Result<(), Error>;
|
||||
fn bool(&mut self, v: bool) -> Result<(), Error>;
|
||||
fn char(&mut self, v: char) -> Result<(), Error>;
|
||||
|
||||
fn str(&mut self, v: &str) -> Result<(), Error>;
|
||||
fn borrowed_str(&mut self, v: &'v str) -> Result<(), Error> {
|
||||
self.str(v)
|
||||
}
|
||||
|
||||
fn none(&mut self) -> Result<(), Error>;
|
||||
|
||||
#[cfg(feature = "kv_unstable_sval")]
|
||||
@ -75,35 +72,45 @@ pub(super) enum Primitive<'v> {
|
||||
None,
|
||||
}
|
||||
|
||||
impl<'v> Primitive<'v> {
|
||||
fn visit(self, visitor: &mut dyn Visitor<'v>) -> Result<(), Error> {
|
||||
match self {
|
||||
Primitive::Signed(value) => visitor.i64(value),
|
||||
Primitive::Unsigned(value) => visitor.u64(value),
|
||||
Primitive::Float(value) => visitor.f64(value),
|
||||
Primitive::Bool(value) => visitor.bool(value),
|
||||
Primitive::Char(value) => visitor.char(value),
|
||||
Primitive::Str(value) => visitor.borrowed_str(value),
|
||||
Primitive::None => visitor.none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod coerce {
|
||||
use super::*;
|
||||
|
||||
impl<'v> Inner<'v> {
|
||||
pub(in crate::kv::value) fn as_str(&self) -> Option<&str> {
|
||||
if let Inner::Primitive(Primitive::Str(value)) = self {
|
||||
Some(value)
|
||||
} else {
|
||||
self.coerce().into_primitive().into_str()
|
||||
}
|
||||
pub(in crate::kv::value) fn get_str(&self) -> Option<&str> {
|
||||
self.coerce().into_primitive().into_str()
|
||||
}
|
||||
|
||||
pub(in crate::kv::value) fn as_u64(&self) -> Option<u64> {
|
||||
pub(in crate::kv::value) fn get_u64(&self) -> Option<u64> {
|
||||
self.coerce().into_primitive().into_u64()
|
||||
}
|
||||
|
||||
pub(in crate::kv::value) fn as_i64(&self) -> Option<i64> {
|
||||
pub(in crate::kv::value) fn get_i64(&self) -> Option<i64> {
|
||||
self.coerce().into_primitive().into_i64()
|
||||
}
|
||||
|
||||
pub(in crate::kv::value) fn as_f64(&self) -> Option<f64> {
|
||||
pub(in crate::kv::value) fn get_f64(&self) -> Option<f64> {
|
||||
self.coerce().into_primitive().into_f64()
|
||||
}
|
||||
|
||||
pub(in crate::kv::value) fn as_char(&self) -> Option<char> {
|
||||
pub(in crate::kv::value) fn get_char(&self) -> Option<char> {
|
||||
self.coerce().into_primitive().into_char()
|
||||
}
|
||||
|
||||
pub(in crate::kv::value) fn as_bool(&self) -> Option<bool> {
|
||||
pub(in crate::kv::value) fn get_bool(&self) -> Option<bool> {
|
||||
self.coerce().into_primitive().into_bool()
|
||||
}
|
||||
|
||||
@ -116,7 +123,7 @@ mod coerce {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> Visitor for Coerce<'v> {
|
||||
impl<'v> Visitor<'v> for Coerce<'v> {
|
||||
fn debug(&mut self, _: &dyn fmt::Debug) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
@ -146,8 +153,13 @@ mod coerce {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn borrowed_str(&mut self, v: &'v str) -> Result<(), Error> {
|
||||
self.0 = Coerced::Primitive(Primitive::Str(v));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn str(&mut self, v: &str) -> Result<(), Error> {
|
||||
fn str(&mut self, _: &str) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -185,6 +197,7 @@ mod coerce {
|
||||
fn into_primitive(self) -> Primitive<'v> {
|
||||
match self {
|
||||
Coerced::Primitive(value) => value,
|
||||
#[cfg(feature = "std")]
|
||||
_ => Primitive::None,
|
||||
}
|
||||
}
|
||||
@ -247,7 +260,7 @@ mod coerce {
|
||||
use std::borrow::Cow;
|
||||
|
||||
impl<'v> Inner<'v> {
|
||||
pub(in crate::kv::value) fn to_str(&self) -> Option<Cow<str>> {
|
||||
pub(in crate::kv::value) fn get_string(&self) -> Option<Cow<str>> {
|
||||
self.coerce().into_string()
|
||||
}
|
||||
}
|
||||
@ -289,6 +302,36 @@ mod fmt_support {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, 'f> Slot<'s, 'f> {
|
||||
/// Fill the slot with a debuggable value.
|
||||
///
|
||||
/// The given value doesn't need to satisfy any particular lifetime constraints.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Calling more than a single `fill` method on this slot will panic.
|
||||
pub fn fill_debug<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where
|
||||
T: fmt::Debug,
|
||||
{
|
||||
self.fill(|visitor| visitor.debug(&value))
|
||||
}
|
||||
|
||||
/// Fill the slot with a displayable value.
|
||||
///
|
||||
/// The given value doesn't need to satisfy any particular lifetime constraints.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Calling more than a single `fill` method on this slot will panic.
|
||||
pub fn fill_display<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where
|
||||
T: fmt::Display,
|
||||
{
|
||||
self.fill(|visitor| visitor.display(&value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> fmt::Debug for kv::Value<'v> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.visit(&mut FmtVisitor(f))?;
|
||||
@ -307,7 +350,7 @@ mod fmt_support {
|
||||
|
||||
struct FmtVisitor<'a, 'b: 'a>(&'a mut fmt::Formatter<'b>);
|
||||
|
||||
impl<'a, 'b: 'a> Visitor for FmtVisitor<'a, 'b> {
|
||||
impl<'a, 'b: 'a, 'v> Visitor<'v> for FmtVisitor<'a, 'b> {
|
||||
fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error> {
|
||||
v.fmt(self.0)?;
|
||||
|
||||
@ -368,6 +411,22 @@ pub(super) mod sval_support {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, 'f> Slot<'s, 'f> {
|
||||
/// Fill the slot with a structured value.
|
||||
///
|
||||
/// The given value doesn't need to satisfy any particular lifetime constraints.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Calling more than a single `fill` method on this slot will panic.
|
||||
pub fn fill_sval<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where
|
||||
T: sval::Value,
|
||||
{
|
||||
self.fill(|visitor| visitor.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(Error::into_sval)?;
|
||||
@ -395,7 +454,7 @@ pub(super) mod sval_support {
|
||||
|
||||
struct SvalVisitor<'a, 'b: 'a>(&'a mut sval::value::Stream<'b>);
|
||||
|
||||
impl<'a, 'b: 'a> Visitor for SvalVisitor<'a, 'b> {
|
||||
impl<'a, 'b: 'a, 'v> Visitor<'v> for SvalVisitor<'a, 'b> {
|
||||
fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error> {
|
||||
self.0
|
||||
.fmt(format_args!("{:?}", v))
|
||||
@ -496,21 +555,21 @@ pub(super) mod sval_support {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coersion() {
|
||||
fn sval_coersion() {
|
||||
assert_eq!(
|
||||
42u64,
|
||||
kv::Value::from_sval(&42u64)
|
||||
.as_u64()
|
||||
.get_u64()
|
||||
.expect("invalid value")
|
||||
);
|
||||
|
||||
assert!(kv::Value::from_sval(&"a string").as_str().is_none());
|
||||
assert!(kv::Value::from_sval(&"a string").get_str().is_none());
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
assert_eq!(
|
||||
"a string",
|
||||
&*kv::Value::from_sval(&"a string")
|
||||
.to_str()
|
||||
.get_string()
|
||||
.expect("invalid value")
|
||||
);
|
||||
}
|
||||
|
@ -53,37 +53,47 @@ where
|
||||
}
|
||||
|
||||
/// A value slot to fill using the [`Fill`](trait.Fill.html) trait.
|
||||
pub struct Slot<'a> {
|
||||
pub struct Slot<'s, 'f> {
|
||||
filled: bool,
|
||||
visitor: &'a mut dyn Visitor,
|
||||
visitor: &'s mut dyn Visitor<'f>,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Slot<'a> {
|
||||
impl<'s, 'f> fmt::Debug for Slot<'s, 'f> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Slot").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Slot<'a> {
|
||||
fn new(visitor: &'a mut dyn Visitor) -> Self {
|
||||
impl<'s, 'f> Slot<'s, 'f> {
|
||||
fn new(visitor: &'s mut dyn Visitor<'f>) -> Self {
|
||||
Slot {
|
||||
visitor,
|
||||
filled: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn fill<F>(&mut self, f: F) -> Result<(), Error>
|
||||
where
|
||||
F: FnOnce(&mut dyn Visitor<'f>) -> Result<(), Error>,
|
||||
{
|
||||
assert!(!self.filled, "the slot has already been filled");
|
||||
self.filled = true;
|
||||
|
||||
f(self.visitor)
|
||||
}
|
||||
|
||||
/// Fill the slot with a value.
|
||||
///
|
||||
/// The given value doesn't need to satisfy any particular lifetime constraints.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Calling `fill` more than once will panic.
|
||||
pub fn fill(&mut self, value: Value) -> Result<(), Error> {
|
||||
assert!(!self.filled, "the slot has already been filled");
|
||||
self.filled = true;
|
||||
|
||||
value.visit(self.visitor)
|
||||
/// Calling more than a single `fill` method on this slot will panic.
|
||||
pub fn fill_any<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where
|
||||
T: Into<Value<'f>>,
|
||||
{
|
||||
self.fill(|visitor| value.into().inner.visit(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,71 +121,71 @@ impl<'v> Value<'v> {
|
||||
}
|
||||
|
||||
/// Try coerce the value into a borrowed string.
|
||||
pub fn as_str(&self) -> Option<&str> {
|
||||
self.inner.as_str()
|
||||
pub fn get_str(&self) -> Option<&str> {
|
||||
self.inner.get_str()
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `u8`.
|
||||
pub fn as_u8(&self) -> Option<u8> {
|
||||
self.inner.as_u64().map(|v| v as u8)
|
||||
pub fn get_u8(&self) -> Option<u8> {
|
||||
self.inner.get_u64().map(|v| v as u8)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `u16`.
|
||||
pub fn as_u16(&self) -> Option<u16> {
|
||||
self.inner.as_u64().map(|v| v as u16)
|
||||
pub fn get_u16(&self) -> Option<u16> {
|
||||
self.inner.get_u64().map(|v| v as u16)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `u32`.
|
||||
pub fn as_u32(&self) -> Option<u32> {
|
||||
self.inner.as_u64().map(|v| v as u32)
|
||||
pub fn get_u32(&self) -> Option<u32> {
|
||||
self.inner.get_u64().map(|v| v as u32)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `u64`.
|
||||
pub fn as_u64(&self) -> Option<u64> {
|
||||
self.inner.as_u64()
|
||||
pub fn get_u64(&self) -> Option<u64> {
|
||||
self.inner.get_u64()
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `i8`.
|
||||
pub fn as_i8(&self) -> Option<i8> {
|
||||
self.inner.as_i64().map(|v| v as i8)
|
||||
pub fn get_i8(&self) -> Option<i8> {
|
||||
self.inner.get_i64().map(|v| v as i8)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `i16`.
|
||||
pub fn as_i16(&self) -> Option<i16> {
|
||||
self.inner.as_i64().map(|v| v as i16)
|
||||
pub fn get_i16(&self) -> Option<i16> {
|
||||
self.inner.get_i64().map(|v| v as i16)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `i32`.
|
||||
pub fn as_i32(&self) -> Option<i32> {
|
||||
self.inner.as_i64().map(|v| v as i32)
|
||||
pub fn get_i32(&self) -> Option<i32> {
|
||||
self.inner.get_i64().map(|v| v as i32)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `i64`.
|
||||
pub fn as_i64(&self) -> Option<i64> {
|
||||
self.inner.as_i64()
|
||||
pub fn get_i64(&self) -> Option<i64> {
|
||||
self.inner.get_i64()
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `f32`.
|
||||
pub fn as_f32(&self) -> Option<f32> {
|
||||
self.inner.as_f64().map(|v| v as f32)
|
||||
pub fn get_f32(&self) -> Option<f32> {
|
||||
self.inner.get_f64().map(|v| v as f32)
|
||||
}
|
||||
|
||||
/// Try coerce the value into a `f64`.
|
||||
pub fn as_f64(&self) -> Option<f64> {
|
||||
self.inner.as_f64()
|
||||
pub fn get_f64(&self) -> Option<f64> {
|
||||
self.inner.get_f64()
|
||||
}
|
||||
|
||||
/// Try coerce the vlaue into a `char`.
|
||||
pub fn as_char(&self) -> Option<char> {
|
||||
self.inner.as_char()
|
||||
/// Try coerce the value into a `char`.
|
||||
pub fn get_char(&self) -> Option<char> {
|
||||
self.inner.get_char()
|
||||
}
|
||||
|
||||
/// Try coerce the vlaue into a `bool`.
|
||||
pub fn as_bool(&self) -> Option<bool> {
|
||||
self.inner.as_bool()
|
||||
/// Try coerce the value into a `bool`.
|
||||
pub fn get_bool(&self) -> Option<bool> {
|
||||
self.inner.get_bool()
|
||||
}
|
||||
|
||||
fn visit(&self, visitor: &mut dyn Visitor) -> Result<(), Error> {
|
||||
fn visit<'a>(&'a self, visitor: &mut dyn Visitor<'a>) -> Result<(), Error> {
|
||||
self.inner.visit(visitor)
|
||||
}
|
||||
}
|
||||
@ -188,8 +198,8 @@ mod std_support {
|
||||
|
||||
impl<'v> Value<'v> {
|
||||
/// Try coerce the value into an owned or borrowed string.
|
||||
pub fn to_str(&self) -> Option<Cow<str>> {
|
||||
self.inner.to_str()
|
||||
pub fn get_string(&self) -> Option<Cow<str>> {
|
||||
self.inner.get_string()
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,19 +214,19 @@ mod std_support {
|
||||
"a string"
|
||||
.to_owned()
|
||||
.to_value()
|
||||
.as_str()
|
||||
.get_str()
|
||||
.expect("invalid value")
|
||||
);
|
||||
assert_eq!(
|
||||
"a string",
|
||||
&*"a string".to_value().to_str().expect("invalid value")
|
||||
&*"a string".to_value().get_string().expect("invalid value")
|
||||
);
|
||||
assert_eq!(
|
||||
"a string",
|
||||
&*"a string"
|
||||
.to_owned()
|
||||
.to_value()
|
||||
.to_str()
|
||||
.get_string()
|
||||
.expect("invalid value")
|
||||
);
|
||||
}
|
||||
@ -228,20 +238,31 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fill_value() {
|
||||
fn fill_value_borrowed() {
|
||||
struct TestFill;
|
||||
|
||||
impl Fill for TestFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
let dbg: &dyn fmt::Debug = &1;
|
||||
|
||||
slot.fill(Value::from_debug(&dbg))
|
||||
slot.fill_debug(&dbg)
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("1", Value::from_fill(&TestFill).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fill_value_owned() {
|
||||
struct TestFill;
|
||||
|
||||
impl Fill for TestFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
slot.fill_any("a string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn fill_multiple_times_panics() {
|
||||
@ -249,8 +270,8 @@ mod tests {
|
||||
|
||||
impl Fill for BadFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
slot.fill(42.into())?;
|
||||
slot.fill(6789.into())?;
|
||||
slot.fill_any(42)?;
|
||||
slot.fill_any(6789)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -263,27 +284,48 @@ mod tests {
|
||||
fn primitive_coercion() {
|
||||
assert_eq!(
|
||||
"a string",
|
||||
"a string".to_value().as_str().expect("invalid value")
|
||||
"a string".to_value().get_str().expect("invalid value")
|
||||
);
|
||||
assert_eq!(
|
||||
"a string",
|
||||
Some("a string").to_value().as_str().expect("invalid value")
|
||||
Some("a string")
|
||||
.to_value()
|
||||
.get_str()
|
||||
.expect("invalid value")
|
||||
);
|
||||
|
||||
assert_eq!(1u8, 1u64.to_value().as_u8().expect("invalid value"));
|
||||
assert_eq!(1u16, 1u64.to_value().as_u16().expect("invalid value"));
|
||||
assert_eq!(1u32, 1u64.to_value().as_u32().expect("invalid value"));
|
||||
assert_eq!(1u64, 1u64.to_value().as_u64().expect("invalid value"));
|
||||
assert_eq!(1u8, 1u64.to_value().get_u8().expect("invalid value"));
|
||||
assert_eq!(1u16, 1u64.to_value().get_u16().expect("invalid value"));
|
||||
assert_eq!(1u32, 1u64.to_value().get_u32().expect("invalid value"));
|
||||
assert_eq!(1u64, 1u64.to_value().get_u64().expect("invalid value"));
|
||||
|
||||
assert_eq!(-1i8, -1i64.to_value().as_i8().expect("invalid value"));
|
||||
assert_eq!(-1i16, -1i64.to_value().as_i16().expect("invalid value"));
|
||||
assert_eq!(-1i32, -1i64.to_value().as_i32().expect("invalid value"));
|
||||
assert_eq!(-1i64, -1i64.to_value().as_i64().expect("invalid value"));
|
||||
assert_eq!(-1i8, -1i64.to_value().get_i8().expect("invalid value"));
|
||||
assert_eq!(-1i16, -1i64.to_value().get_i16().expect("invalid value"));
|
||||
assert_eq!(-1i32, -1i64.to_value().get_i32().expect("invalid value"));
|
||||
assert_eq!(-1i64, -1i64.to_value().get_i64().expect("invalid value"));
|
||||
|
||||
assert!(1f32.to_value().as_f32().is_some(), "invalid value");
|
||||
assert!(1f64.to_value().as_f64().is_some(), "invalid value");
|
||||
assert!(1f32.to_value().get_f32().is_some(), "invalid value");
|
||||
assert!(1f64.to_value().get_f64().is_some(), "invalid value");
|
||||
|
||||
assert_eq!('a', 'a'.to_value().as_char().expect("invalid value"));
|
||||
assert_eq!(true, true.to_value().as_bool().expect("invalid value"));
|
||||
assert_eq!('a', 'a'.to_value().get_char().expect("invalid value"));
|
||||
assert_eq!(true, true.to_value().get_bool().expect("invalid value"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fill_coercion() {
|
||||
struct TestFill;
|
||||
|
||||
impl Fill for TestFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
slot.fill_any("a string")
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
"a string",
|
||||
Value::from_fill(&TestFill)
|
||||
.get_str()
|
||||
.expect("invalid value")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ impl<'v> Value<'v> {
|
||||
pub(in kv) fn to_token(&self) -> Token {
|
||||
struct TestVisitor(Option<Token>);
|
||||
|
||||
impl internal::Visitor for TestVisitor {
|
||||
impl<'v> internal::Visitor<'v> for TestVisitor {
|
||||
fn debug(&mut self, v: &dyn fmt::Debug) -> Result<(), Error> {
|
||||
self.0 = Some(Token::Str(format!("{:?}", v)));
|
||||
Ok(())
|
||||
|
19
src/lib.rs
19
src/lib.rs
@ -1648,4 +1648,23 @@ mod tests {
|
||||
|
||||
assert_eq!(2, visitor.seen_pairs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "kv_unstable")]
|
||||
fn test_record_key_values_get_coerce() {
|
||||
use super::Record;
|
||||
|
||||
let kvs: &[(&str, i32)] = &[("a", 1), ("b", 2)];
|
||||
let record = Record::builder().key_values(&kvs).build();
|
||||
|
||||
assert_eq!(
|
||||
1,
|
||||
record
|
||||
.key_values()
|
||||
.get("a".into())
|
||||
.expect("missing key")
|
||||
.get_i32()
|
||||
.expect("invalid value")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user