//! Structured logging.
//!
//! Add the `kv` feature to your `Cargo.toml` to enable
//! this module:
//!
//! ```toml
//! [dependencies.log]
//! features = ["kv"]
//! ```
//!
//! # Structured logging in `log`
//!
//! Structured logging enhances traditional text-based log records with user-defined
//! attributes. Structured logs can be analyzed using a variety of data processing
//! techniques, without needing to find and parse attributes from unstructured text first.
//!
//! In `log`, user-defined attributes are part of a [`Source`] on the log record.
//! Each attribute is a key-value; a pair of [`Key`] and [`Value`]. Keys are strings
//! and values are a datum of any type that can be formatted or serialized. Simple types
//! like strings, booleans, and numbers are supported, as well as arbitrarily complex
//! structures involving nested objects and sequences.
//!
//! ## Adding key-values to log records
//!
//! Key-values appear before the message format in the `log!` macros:
//!
//! ```
//! # use log::info;
//! info!(a = 1; "Something of interest");
//! ```
//!
//! Key-values support the same shorthand identifer syntax as `format_args`:
//!
//! ```
//! # use log::info;
//! let a = 1;
//!
//! info!(a; "Something of interest");
//! ```
//!
//! Values are capturing using the [`ToValue`] trait by default. To capture a value
//! using a different trait implementation, use a modifier after its key. Here's how
//! the same example can capture `a` using its `Debug` implementation instead:
//!
//! ```
//! # use log::info;
//! info!(a:? = 1; "Something of interest");
//! ```
//!
//! The following capturing modifiers are supported:
//!
//! - `:?` will capture the value using `Debug`.
//! - `:debug` will capture the value using `Debug`.
//! - `:%` will capture the value using `Display`.
//! - `:display` will capture the value using `Display`.
//! - `:err` will capture the value using `std::error::Error` (requires the `kv_std` feature).
//! - `:sval` will capture the value using `sval::Value` (requires the `kv_sval` feature).
//! - `:serde` will capture the value using `serde::Serialize` (requires the `kv_serde` feature).
//!
//! ## Working with key-values on log records
//!
//! Use the [`Record::key_values`](../struct.Record.html#method.key_values) method to access key-values.
//!
//! Individual values can be pulled from the source by their key:
//!
//! ```
//! # fn main() -> Result<(), log::kv::Error> {
//! use log::kv::{Source, Key, Value};
//! # let record = log::Record::builder().key_values(&[("a", 1)]).build();
//!
//! // info!(a = 1; "Something of interest");
//!
//! let a: Value = record.key_values().get(Key::from("a")).unwrap();
//! assert_eq!(1, a.to_i64().unwrap());
//! # Ok(())
//! # }
//! ```
//!
//! All key-values can also be enumerated using a [`VisitSource`]:
//!
//! ```
//! # fn main() -> Result<(), log::kv::Error> {
//! use std::collections::BTreeMap;
//!
//! use log::kv::{self, Source, Key, Value, VisitSource};
//!
//! struct Collect<'kvs>(BTreeMap<Key<'kvs>, Value<'kvs>>);
//!
//! impl<'kvs> VisitSource<'kvs> for Collect<'kvs> {
//!     fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), kv::Error> {
//!         self.0.insert(key, value);
//!
//!         Ok(())
//!     }
//! }
//!
//! let mut visitor = Collect(BTreeMap::new());
//!
//! # let record = log::Record::builder().key_values(&[("a", 1), ("b", 2), ("c", 3)]).build();
//! // info!(a = 1, b = 2, c = 3; "Something of interest");
//!
//! record.key_values().visit(&mut visitor)?;
//!
//! let collected = visitor.0;
//!
//! assert_eq!(
//!     vec!["a", "b", "c"],
//!     collected
//!         .keys()
//!         .map(|k| k.as_str())
//!         .collect::<Vec<_>>(),
//! );
//! # Ok(())
//! # }
//! ```
//!
//! [`Value`]s have methods for conversions to common types:
//!
//! ```
//! # fn main() -> Result<(), log::kv::Error> {
//! use log::kv::{Source, Key};
//! # let record = log::Record::builder().key_values(&[("a", 1)]).build();
//!
//! // info!(a = 1; "Something of interest");
//!
//! let a = record.key_values().get(Key::from("a")).unwrap();
//!
//! assert_eq!(1, a.to_i64().unwrap());
//! # Ok(())
//! # }
//! ```
//!
//! Values also have their own [`VisitValue`] type. Value visitors are a lightweight
//! API for working with primitives types:
//!
//! ```
//! # fn main() -> Result<(), log::kv::Error> {
//! use log::kv::{self, Source, Key, VisitValue};
//! # let record = log::Record::builder().key_values(&[("a", 1)]).build();
//!
//! struct IsNumeric(bool);
//!
//! impl<'kvs> VisitValue<'kvs> for IsNumeric {
//!     fn visit_any(&mut self, _value: kv::Value) -> Result<(), kv::Error> {
//!         self.0 = false;
//!         Ok(())
//!     }
//!
//!     fn visit_u64(&mut self, _value: u64) -> Result<(), kv::Error> {
//!         self.0 = true;
//!         Ok(())
//!     }
//!
//!     fn visit_i64(&mut self, _value: i64) -> Result<(), kv::Error> {
//!         self.0 = true;
//!         Ok(())
//!     }
//!
//!     fn visit_u128(&mut self, _value: u128) -> Result<(), kv::Error> {
//!         self.0 = true;
//!         Ok(())
//!     }
//!
//!     fn visit_i128(&mut self, _value: i128) -> Result<(), kv::Error> {
//!         self.0 = true;
//!         Ok(())
//!     }
//!
//!     fn visit_f64(&mut self, _value: f64) -> Result<(), kv::Error> {
//!         self.0 = true;
//!         Ok(())
//!     }
//! }
//!
//! // info!(a = 1; "Something of interest");
//!
//! let a = record.key_values().get(Key::from("a")).unwrap();
//!
//! let mut visitor = IsNumeric(false);
//!
//! a.visit(&mut visitor)?;
//!
//! let is_numeric = visitor.0;
//!
//! assert!(is_numeric);
//! # Ok(())
//! # }
//! ```
//!
//! To serialize a value to a format like JSON, you can also use either `serde` or `sval`:
//!
//! ```
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # #[cfg(feature = "serde")]
//! # {
//! # use log::kv::Key;
//! #[derive(serde::Serialize)]
//! struct Data {
//!     a: i32, b: bool,
//!     c: &'static str,
//! }
//!
//! let data = Data { a: 1, b: true, c: "Some data" };
//!
//! # let source = [("a", log::kv::Value::from_serde(&data))];
//! # let record = log::Record::builder().key_values(&source).build();
//! // info!(a = data; "Something of interest");
//!
//! let a = record.key_values().get(Key::from("a")).unwrap();
//!
//! assert_eq!("{\"a\":1,\"b\":true,\"c\":\"Some data\"}", serde_json::to_string(&a)?);
//! # }
//! # Ok(())
//! # }
//! ```
//!
//! The choice of serialization framework depends on the needs of the consumer.
//! If you're in a no-std environment, you can use `sval`. In other cases, you can use `serde`.
//! Log producers and log consumers don't need to agree on the serialization framework.
//! A value can be captured using its `serde::Serialize` implementation and still be serialized
//! through `sval` without losing any structure or data.
//!
//! Values can also always be formatted using the standard `Debug` and `Display`
//! traits:
//!
//! ```
//! # use log::kv::Key;
//! # #[derive(Debug)]
//! struct Data {
//!     a: i32,
//!     b: bool,
//!     c: &'static str,
//! }
//!
//! let data = Data { a: 1, b: true, c: "Some data" };
//!
//! # let source = [("a", log::kv::Value::from_debug(&data))];
//! # let record = log::Record::builder().key_values(&source).build();
//! // info!(a = data; "Something of interest");
//!
//! let a = record.key_values().get(Key::from("a")).unwrap();
//!
//! assert_eq!("Data { a: 1, b: true, c: \"Some data\" }", format!("{a:?}"));
//! ```

mod error;
mod key;

#[cfg(not(feature = "kv_unstable"))]
mod source;
#[cfg(not(feature = "kv_unstable"))]
mod value;

pub use self::error::Error;
pub use self::key::{Key, ToKey};
pub use self::source::{Source, VisitSource};
pub use self::value::{ToValue, Value, VisitValue};

#[cfg(feature = "kv_unstable")]
pub mod source;
#[cfg(feature = "kv_unstable")]
pub mod value;

#[cfg(feature = "kv_unstable")]
pub use self::source::Visitor;
