diem_logger/
kv.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8//! Key-Value definitions for macros
9//!
10//! Example:
11//! ```
12//! use diem_logger::info;
13//! info!(key = "value");
14//! ```
15
16use serde::Serialize;
17use std::fmt;
18
19/// The key part of a logging key value pair e.g. `info!(key = value)`
20#[derive(
21    Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize,
22)]
23pub struct Key(&'static str);
24
25impl Key {
26    pub fn new(s: &'static str) -> Self { Self(s) }
27
28    pub fn as_str(&self) -> &'static str { self.0 }
29}
30
31/// The value part of a logging key value pair e.g. `info!(key = value)`
32#[derive(Clone, Copy)]
33pub enum Value<'v> {
34    Debug(&'v dyn fmt::Debug),
35    Display(&'v dyn fmt::Display),
36    Serde(&'v dyn erased_serde::Serialize),
37}
38
39impl<'v> fmt::Debug for Value<'v> {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match &self {
42            Value::Debug(d) => fmt::Debug::fmt(d, f),
43            Value::Display(d) => fmt::Display::fmt(d, f),
44            Value::Serde(s) => fmt::Debug::fmt(
45                &serde_json::to_value(s).map_err(|_| fmt::Error)?,
46                f,
47            ),
48        }
49    }
50}
51
52impl<'v> Value<'v> {
53    /// Get a value from a debuggable type.
54    pub fn from_serde<T: serde::Serialize>(value: &'v T) -> Self {
55        Value::Serde(value)
56    }
57
58    /// Get a value from a debuggable type.
59    pub fn from_debug<T: fmt::Debug>(value: &'v T) -> Self {
60        Value::Debug(value)
61    }
62
63    /// Get a value from a displayable type.
64    pub fn from_display<T: fmt::Display>(value: &'v T) -> Self {
65        Value::Display(value)
66    }
67}
68
69/// The logging key value pair e.g. `info!(key = value)`
70#[derive(Clone, Debug)]
71pub struct KeyValue<'v> {
72    key: Key,
73    value: Value<'v>,
74}
75
76impl<'v> KeyValue<'v> {
77    pub fn new(key: &'static str, value: Value<'v>) -> Self {
78        Self {
79            key: Key::new(key),
80            value,
81        }
82    }
83}
84
85impl<'v> Schema for KeyValue<'v> {
86    fn visit(&self, visitor: &mut dyn Visitor) {
87        visitor.visit_pair(self.key, self.value)
88    }
89}
90
91/// A schema of key-value pairs.
92///
93/// The schema may be a single pair, a set of pairs, or a filter over a set of
94/// pairs. Use the [`Visitor`](trait.Visitor.html) trait to inspect the
95/// structured data in a schema.
96pub trait Schema {
97    /// Visit key-value pairs.
98    fn visit(&self, visitor: &mut dyn Visitor);
99}
100
101/// A visitor for the key-value pairs in a [`Schema`](trait.Schema.html).
102pub trait Visitor {
103    /// Visit a key-value pair.
104    fn visit_pair(&mut self, key: Key, value: Value<'_>);
105}
106
107impl<'a, 'b: 'a> Visitor for fmt::DebugMap<'a, 'b> {
108    fn visit_pair(&mut self, key: Key, value: Value<'_>) {
109        self.entry(&key, &value);
110    }
111}