timber_rust/factory/
vec.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4use crate::{Concurrency, DirectLogger, Logger, QueuedLogger, service};
5
6/// A factory for creating loggers that store messages in an in-memory [`Vec`].
7///
8/// The `Vector` factory is ideal for unit testing, allowing you to capture
9/// logs in a thread-safe list and verify them later. Unlike string-based loggers,
10/// this preserves the structured [`Message`][`crate::Message`] data.
11///
12/// ### Default Configuration
13/// - **Capacity**: `1024` (Pre-allocated slots for log messages).
14/// - **Max Retries**: `3` (Attempts to re-send if the buffer is temporarily locked).
15/// - **Worker Count**: `1` (Ensures sequential insertion order in async mode).
16pub struct Vector {
17    capacity: usize,
18    max_retries: usize,
19    worker_count: usize,
20}
21
22impl Vector {
23    /// Creates a new `Vector` factory with explicit settings.
24    pub fn new(capacity: usize, max_retries: usize, worker_count: usize) -> Self {
25        Self {
26            capacity,
27            max_retries,
28            worker_count,
29        }
30    }
31
32    /// Returns the initial pre-allocated capacity for the message buffer.
33    pub fn get_capacity(&self) -> usize {
34        self.capacity
35    }
36
37    /// Returns the currently configured maximum retry attempts.
38    pub fn get_max_retries(&self) -> usize {
39        self.max_retries
40    }
41
42    /// Returns the currently configured background worker count.
43    pub fn get_worker_count(&self) -> usize {
44        self.worker_count
45    }
46
47    /// Sets the initial capacity of the internal vector.
48    ///
49    /// Pre-allocating capacity helps avoid expensive reallocations during 
50    /// high-frequency logging events.
51    pub fn capacity(self, capacity: usize) -> Self {
52        Self { capacity, ..self }
53    }
54
55    /// Updates the maximum number of retry attempts for the buffer.
56    pub fn max_retries(self, max_retries: usize) -> Self {
57        Self {
58            max_retries,
59            ..self
60        }
61    }
62
63    /// Updates the background worker count. 
64    ///
65    /// Note: Using multiple workers with a vector may result in logs being 
66    /// inserted out of chronological order.
67    pub fn worker_count(self, worker_count: usize) -> Self {
68        Self {
69            worker_count,
70            ..self
71        }
72    }
73
74    /// Finalizes the builder and returns a high-level [`Logger`].
75    pub fn build(self, concurrency: Concurrency) -> Logger {
76        match concurrency {
77            Concurrency::Sync => Logger::new(self.build_impl_direct()),
78            Concurrency::Async => Logger::new(self.build_impl_queued()),
79        }
80    }
81
82    /// Builds the underlying [`DirectLogger`] implementation.
83    pub fn build_impl_direct(self) -> Box<DirectLogger> {
84        let max_retries = self.max_retries;
85        DirectLogger::new(self.build_service(), max_retries)
86    }
87
88    /// Builds the underlying [`QueuedLogger`] implementation.
89    pub fn build_impl_queued(self) -> Box<QueuedLogger> {
90        let max_retries = self.max_retries;
91        let worker_count = self.worker_count;
92        QueuedLogger::new(self.build_service(), max_retries, worker_count)
93    }
94
95    /// Internal helper to construct the [`service::Vector`] instance.
96    pub fn build_service(self) -> Box<service::Vector> {
97        service::Vector::new(self.capacity)
98    }
99}
100
101impl Default for Vector {
102    /// Provides sensible defaults for in-memory message capturing.
103    ///
104    /// - **capacity**: `1024`
105    /// - **max_retries**: `3`
106    /// - **worker_count**: `1`
107    fn default() -> Self {
108        Self {
109            capacity: 1024usize,
110            max_retries: 3,
111            worker_count: 1,
112        }
113    }
114}