context_logger/context.rs
1//! Context builder for structured logging.
2
3use std::borrow::Cow;
4
5use crate::{LogValue, fields::LogFields};
6
7/// A set of fields that can be attached to a logging scope.
8///
9/// Fields are split into two categories:
10///
11/// - **local** - fields belonging only to the current scope. They do not propagate to child scopes.
12/// - **inherited** - fields that automatically flow into all child scopes created within the
13/// current scope.
14///
15/// Nested scopes resolution rules:
16///
17/// - child `inherited` overwrites parent `inherited` by key
18/// - inherited are emitted before local, so "last write wins" consumers see local shadowing
19#[derive(Debug, Default, Clone)]
20pub struct LogContext {
21 /// Fields belonging only to the current scope.
22 pub local: LogFields,
23 /// Fields that automatically flow into all child scopes created within the
24 /// current scope.
25 pub inherited: LogFields,
26}
27
28impl LogContext {
29 /// Creates a new, empty context.
30 #[must_use]
31 pub fn new() -> Self {
32 Self::default()
33 }
34
35 /// Adds a key-value field to the local fields of this context.
36 ///
37 /// See [`LogFields`] for more details about log fields.
38 #[must_use]
39 pub fn with_local_field(
40 mut self,
41 key: impl Into<Cow<'static, str>>,
42 value: impl Into<LogValue>,
43 ) -> Self {
44 self.local = self.local.with(key, value);
45 self
46 }
47
48 /// Adds a key-value pair to the inherited fields of this context.
49 ///
50 /// See [`LogFields`] for more details about log fields.
51 #[must_use]
52 pub fn with_inherited_field(
53 mut self,
54 key: impl Into<Cow<'static, str>>,
55 value: impl Into<LogValue>,
56 ) -> Self {
57 self.inherited = self.inherited.with(key, value);
58 self
59 }
60
61 /// Returns `true` if both local and inherited fields are empty.
62 #[must_use]
63 pub fn is_empty(&self) -> bool {
64 self.local.is_empty() && self.inherited.is_empty()
65 }
66}