mirror of
https://gitee.com/openharmony/third_party_rust_log
synced 2024-11-27 09:50:34 +00:00
Make it easier to create a Value from owned or erased external types (#339)
* refactor Value internals to avoid needing to buffer that means doing two things: 1. allowing us to create a value with any lifetime from some owned primitive, like u8, bool etc 2. allowing us to create a value from some type that _can_ produce a concrete value we can use, but doesn't guarantee it will live as long as the value itself * add test for Fill
This commit is contained in:
parent
a764fdaad8
commit
9b71d367a0
@ -3,7 +3,7 @@
|
||||
mod error;
|
||||
mod source;
|
||||
mod key;
|
||||
mod value;
|
||||
pub mod value;
|
||||
|
||||
pub use self::error::Error;
|
||||
pub use self::source::{Source, Visitor};
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Sources for key-value pairs.
|
||||
|
||||
use std::fmt;
|
||||
use kv::{Error, Key, ToKey, Value, ToValue};
|
||||
|
||||
/// A source of key-value pairs.
|
||||
@ -168,6 +169,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> {
|
||||
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
|
||||
self.entry(&key, &value);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> {
|
||||
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
|
||||
self.entry(&(key, value));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> {
|
||||
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
|
||||
self.entry(&(key, value));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> {
|
||||
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
|
||||
self.field(&key);
|
||||
self.field(&value);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod std_support {
|
||||
use super::*;
|
||||
|
@ -1,196 +1,190 @@
|
||||
use std::fmt;
|
||||
|
||||
use super::{Error, ToValue, Value, Visit, Visitor};
|
||||
use super::{ToValue, Value, Primitive};
|
||||
|
||||
impl ToValue for usize {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for usize {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.u64(*self as u64)
|
||||
impl<'v> From<usize> for Value<'v> {
|
||||
fn from(value: usize) -> Self {
|
||||
Value::from_primitive(Primitive::Unsigned(value as u64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for isize {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for isize {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.i64(*self as i64)
|
||||
impl<'v> From<isize> for Value<'v> {
|
||||
fn from(value: isize) -> Self {
|
||||
Value::from_primitive(Primitive::Signed(value as i64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for u8 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for u8 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.u64(*self as u64)
|
||||
impl<'v> From<u8> for Value<'v> {
|
||||
fn from(value: u8) -> Self {
|
||||
Value::from_primitive(Primitive::Unsigned(value as u64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for u16 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for u16 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.u64(*self as u64)
|
||||
impl<'v> From<u16> for Value<'v> {
|
||||
fn from(value: u16) -> Self {
|
||||
Value::from_primitive(Primitive::Unsigned(value as u64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for u32 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for u32 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.u64(*self as u64)
|
||||
impl<'v> From<u32> for Value<'v> {
|
||||
fn from(value: u32) -> Self {
|
||||
Value::from_primitive(Primitive::Unsigned(value as u64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for u64 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for u64 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.u64(*self)
|
||||
impl<'v> From<u64> for Value<'v> {
|
||||
fn from(value: u64) -> Self {
|
||||
Value::from_primitive(Primitive::Unsigned(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for i8 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for i8 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.i64(*self as i64)
|
||||
impl<'v> From<i8> for Value<'v> {
|
||||
fn from(value: i8) -> Self {
|
||||
Value::from_primitive(Primitive::Signed(value as i64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for i16 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for i16 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.i64(*self as i64)
|
||||
impl<'v> From<i16> for Value<'v> {
|
||||
fn from(value: i16) -> Self {
|
||||
Value::from_primitive(Primitive::Signed(value as i64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for i32 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for i32 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.i64(*self as i64)
|
||||
impl<'v> From<i32> for Value<'v> {
|
||||
fn from(value: i32) -> Self {
|
||||
Value::from_primitive(Primitive::Signed(value as i64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for i64 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for i64 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.i64(*self)
|
||||
impl<'v> From<i64> for Value<'v> {
|
||||
fn from(value: i64) -> Self {
|
||||
Value::from_primitive(Primitive::Signed(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for f32 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for f32 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.f64(*self as f64)
|
||||
impl<'v> From<f32> for Value<'v> {
|
||||
fn from(value: f32) -> Self {
|
||||
Value::from_primitive(Primitive::Float(value as f64))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for f64 {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for f64 {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.f64(*self)
|
||||
impl<'v> From<f64> for Value<'v> {
|
||||
fn from(value: f64) -> Self {
|
||||
Value::from_primitive(Primitive::Float(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for bool {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for bool {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.bool(*self)
|
||||
impl<'v> From<bool> for Value<'v> {
|
||||
fn from(value: bool) -> Self {
|
||||
Value::from_primitive(Primitive::Bool(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for char {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for char {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.char(*self)
|
||||
impl<'v> From<char> for Value<'v> {
|
||||
fn from(value: char) -> Self {
|
||||
Value::from_primitive(Primitive::Char(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> ToValue for &'v str {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> Visit for &'v str {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.str(*self)
|
||||
impl<'v> From<&'v str> for Value<'v> {
|
||||
fn from(value: &'v str) -> Self {
|
||||
Value::from_primitive(Primitive::Str(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for () {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for () {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.none()
|
||||
Value::from_primitive(Primitive::None)
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,18 +193,9 @@ where
|
||||
T: ToValue,
|
||||
{
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visit for Option<T>
|
||||
where
|
||||
T: ToValue,
|
||||
{
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
match *self {
|
||||
Some(ref value) => value.to_value().visit(visitor),
|
||||
None => visitor.none(),
|
||||
Some(ref value) => value.to_value(),
|
||||
None => Value::from_primitive(Primitive::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -238,25 +223,13 @@ mod std_support {
|
||||
|
||||
impl ToValue for String {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
Value::from_primitive(Primitive::Str(&*self))
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for String {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.str(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToValue for Cow<'a, str> {
|
||||
impl<'v> ToValue for Cow<'v, str> {
|
||||
fn to_value(&self) -> Value {
|
||||
Value::from_internal(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit for Cow<'a, str> {
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
visitor.str(&*self)
|
||||
Value::from_primitive(Primitive::Str(&*self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::fmt;
|
||||
|
||||
use super::Error;
|
||||
use super::{Fill, Slot, Error};
|
||||
|
||||
// `Visit` and `Visitor` is an internal API for visiting the structure of a value.
|
||||
// It's not intended to be public (at this stage).
|
||||
@ -12,9 +12,10 @@ use super::Error;
|
||||
/// A container for a structured value for a specific kind of visitor.
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) enum Inner<'v> {
|
||||
/// An internal `Visit`. It'll be an internal structure-preserving
|
||||
/// type from the standard library that's implemented in this crate.
|
||||
Internal(&'v Visit),
|
||||
/// A simple primitive value that can be copied without allocating.
|
||||
Primitive(Primitive<'v>),
|
||||
/// A value that can be filled.
|
||||
Fill(&'v Fill),
|
||||
/// A debuggable value.
|
||||
Debug(&'v fmt::Debug),
|
||||
/// A displayable value.
|
||||
@ -24,18 +25,22 @@ pub(super) enum Inner<'v> {
|
||||
impl<'v> Inner<'v> {
|
||||
pub(super) fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
match *self {
|
||||
Inner::Internal(ref value) => value.visit(visitor),
|
||||
Inner::Debug(ref value) => visitor.debug(value),
|
||||
Inner::Display(ref value) => visitor.display(value),
|
||||
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(),
|
||||
},
|
||||
Inner::Fill(value) => value.fill(&mut Slot::new(visitor)),
|
||||
Inner::Debug(value) => visitor.debug(value),
|
||||
Inner::Display(value) => visitor.display(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal structure-preserving value.
|
||||
pub(super) trait Visit {
|
||||
fn visit(&self, backend: &mut Visitor) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// The internal serialization contract.
|
||||
pub(super) trait Visitor {
|
||||
fn debug(&mut self, v: &fmt::Debug) -> Result<(), Error>;
|
||||
@ -52,6 +57,17 @@ pub(super) trait Visitor {
|
||||
fn none(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) enum Primitive<'v> {
|
||||
Signed(i64),
|
||||
Unsigned(u64),
|
||||
Float(f64),
|
||||
Bool(bool),
|
||||
Char(char),
|
||||
Str(&'v str),
|
||||
None,
|
||||
}
|
||||
|
||||
/// A visitor for `std::fmt`.
|
||||
pub(super) struct FmtVisitor<'a, 'b: 'a>(pub(super) &'a mut fmt::Formatter<'b>);
|
||||
|
||||
|
@ -8,9 +8,9 @@ mod impls;
|
||||
#[cfg(test)]
|
||||
pub(in kv) mod test;
|
||||
|
||||
use kv::Error;
|
||||
pub use kv::Error;
|
||||
|
||||
use self::internal::{Inner, Visit, Visitor};
|
||||
use self::internal::{Inner, Visitor, Primitive};
|
||||
|
||||
/// A type that can be converted into a [`Value`](struct.Value.html).
|
||||
pub trait ToValue {
|
||||
@ -35,6 +35,60 @@ impl<'v> ToValue for Value<'v> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that requires extra work to convert into a [`Value`](struct.Value.html).
|
||||
///
|
||||
/// This trait is a more advanced initialization API than [`ToValue`](trait.ToValue.html).
|
||||
/// It's intended for erased values coming from other logging frameworks that may need
|
||||
/// to perform extra work to determine the concrete type to use.
|
||||
pub trait Fill {
|
||||
/// Fill a value.
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
impl<'a, T> Fill for &'a T
|
||||
where
|
||||
T: Fill + ?Sized,
|
||||
{
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
(**self).fill(slot)
|
||||
}
|
||||
}
|
||||
|
||||
/// A value slot to fill using the [`Fill`](trait.Fill.html) trait.
|
||||
pub struct Slot<'a> {
|
||||
filled: bool,
|
||||
visitor: &'a mut Visitor,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Slot<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Slot").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Slot<'a> {
|
||||
fn new(visitor: &'a mut Visitor) -> Self {
|
||||
Slot {
|
||||
visitor,
|
||||
filled: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
}
|
||||
|
||||
/// A value in a structured key-value pair.
|
||||
pub struct Value<'v> {
|
||||
inner: Inner<'v>,
|
||||
@ -42,12 +96,9 @@ pub struct Value<'v> {
|
||||
|
||||
impl<'v> Value<'v> {
|
||||
/// Get a value from an internal `Visit`.
|
||||
fn from_internal<T>(value: &'v T) -> Self
|
||||
where
|
||||
T: Visit,
|
||||
{
|
||||
fn from_primitive(value: Primitive<'v>) -> Self {
|
||||
Value {
|
||||
inner: Inner::Internal(value),
|
||||
inner: Inner::Primitive(value),
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +112,8 @@ impl<'v> Value<'v> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a value from a displayable type.
|
||||
pub fn from_display<T>(value: &'v T) -> Self
|
||||
/// Get a value from a displayable type.
|
||||
pub fn from_display<T>(value: &'v T) -> Self
|
||||
where
|
||||
T: fmt::Display,
|
||||
{
|
||||
@ -71,6 +122,16 @@ impl<'v> Value<'v> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a value from a fillable slot.
|
||||
pub fn from_fill<T>(value: &'v T) -> Self
|
||||
where
|
||||
T: Fill,
|
||||
{
|
||||
Value {
|
||||
inner: Inner::Fill(value),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit(&self, visitor: &mut Visitor) -> Result<(), Error> {
|
||||
self.inner.visit(visitor)
|
||||
}
|
||||
@ -91,3 +152,40 @@ impl<'v> fmt::Display for Value<'v> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fill_value() {
|
||||
struct TestFill;
|
||||
|
||||
impl Fill for TestFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
let dbg: &fmt::Debug = &1;
|
||||
|
||||
slot.fill(Value::from_debug(&dbg))
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("1", Value::from_fill(&TestFill).to_str_buf());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn fill_multiple_times_panics() {
|
||||
struct BadFill;
|
||||
|
||||
impl Fill for BadFill {
|
||||
fn fill(&self, slot: &mut Slot) -> Result<(), Error> {
|
||||
slot.fill(42.into())?;
|
||||
slot.fill(6789.into())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let _ = Value::from_fill(&BadFill).to_str_buf();
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,12 @@ impl<'a> PartialEq<&'a str> for StrBuf {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<StrBuf> for &'a str {
|
||||
fn eq(&self, other: &StrBuf) -> bool {
|
||||
*self == other.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for StrBuf {
|
||||
fn as_ref(&self) -> &str {
|
||||
str::from_utf8(&self.buf[0..self.len]).unwrap()
|
||||
|
16
src/lib.rs
16
src/lib.rs
@ -736,21 +736,9 @@ struct KeyValues<'a>(&'a kv::Source);
|
||||
#[cfg(feature = "kv_unstable")]
|
||||
impl<'a> fmt::Debug for KeyValues<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::kv::{Key, Value, Visitor, Error};
|
||||
|
||||
struct FmtVisitor<'a, 'b: 'a>(fmt::DebugMap<'a, 'b>);
|
||||
|
||||
impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for FmtVisitor<'a, 'b> {
|
||||
fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
|
||||
self.0.entry(&key, &value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = FmtVisitor(f.debug_map());
|
||||
let mut visitor = f.debug_map();
|
||||
self.0.visit(&mut visitor)?;
|
||||
visitor.0.finish()
|
||||
visitor.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user