Skip to main content

qubit_value/
named_multi_values.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Named Multiple Values
10//!
11//! Provides a lightweight container for binding names to multiple value collections,
12//! facilitating human-readable identification of groups of values in configurations,
13//! serialization, logging, and other scenarios.
14//!
15//! # Author
16//!
17//! Haixing Hu
18
19use serde::{Deserialize, Serialize};
20use std::ops::{Deref, DerefMut};
21
22use super::multi_values::MultiValues;
23use super::named_value::NamedValue;
24
25/// Named multiple values
26///
27/// A container that associates a readable name with a set of `MultiValues`, suitable for
28/// organizing data in key-value (name-multiple values) scenarios, such as configuration items,
29/// command-line parameter aggregation, structured log fields, etc.
30///
31/// # Features
32///
33/// - Provides clear name identification for multiple value collections
34/// - Transparently reuses all capabilities of `MultiValues` through `Deref/DerefMut`
35/// - Supports `serde` serialization and deserialization
36///
37/// # Use Cases
38///
39/// - Aggregating a set of ports, hostnames, etc., as semantically meaningful fields
40/// - Outputting named multiple value lists in configurations/logs
41///
42/// # Example
43///
44/// ```rust
45/// use common_rs::util::value::{NamedMultiValues, MultiValues};
46///
47/// // Identify a group of ports with the name "ports"
48/// let named = NamedMultiValues::new(
49///     "ports",
50///     MultiValues::Int32(vec![8080, 8081, 8082])
51/// );
52///
53/// assert_eq!(named.name(), "ports");
54/// assert_eq!(named.count(), 3);
55/// ```
56///
57/// # Author
58///
59/// Haixing Hu
60///
61#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
62pub struct NamedMultiValues {
63    /// Name of the values
64    name: String,
65    /// Content of the multiple values
66    value: MultiValues,
67}
68
69impl NamedMultiValues {
70    /// Create a new named multiple values
71    ///
72    /// Associates a given name with `MultiValues`, generating a container that can be referenced by name.
73    ///
74    /// # Use Cases
75    ///
76    /// - Building configuration fields (e.g., `servers`, `ports`, etc.)
77    /// - Binding parsed multiple value results to semantic names
78    ///
79    /// # Parameters
80    ///
81    /// * `name` - Name of the multiple values
82    /// * `value` - Content of the multiple values
83    ///
84    /// # Returns
85    ///
86    /// Returns a newly created named multiple values
87    ///
88    /// # Example
89    ///
90    /// ```rust
91    /// use common_rs::util::value::{NamedMultiValues, MultiValues};
92    ///
93    /// let named = NamedMultiValues::new(
94    ///     "servers",
95    ///     MultiValues::String(vec!["s1".to_string(), "s2".to_string()])
96    /// );
97    /// assert_eq!(named.name(), "servers");
98    /// ```
99    #[inline]
100    pub fn new(name: impl Into<String>, value: MultiValues) -> Self {
101        Self {
102            name: name.into(),
103            value,
104        }
105    }
106
107    /// Get a reference to the name
108    ///
109    /// # Returns
110    ///
111    /// Returns a string slice of the name
112    ///
113    /// # Example
114    ///
115    /// ```rust
116    /// use common_rs::util::value::{NamedMultiValues, MultiValues};
117    ///
118    /// let named = NamedMultiValues::new("items", MultiValues::Int32(vec![1, 2, 3]));
119    /// assert_eq!(named.name(), "items");
120    /// ```
121    #[inline]
122    pub fn name(&self) -> &str {
123        &self.name
124    }
125
126    // Methods of MultiValues are forwarded through Deref/DerefMut
127
128    /// Set a new name
129    ///
130    /// # Parameters
131    ///
132    /// * `name` - The new name
133    ///
134    /// # Returns
135    ///
136    /// No return value
137    ///
138    /// # Example
139    ///
140    /// ```rust
141    /// use common_rs::util::value::{NamedMultiValues, MultiValues};
142    ///
143    /// let mut named = NamedMultiValues::new("old", MultiValues::Bool(vec![true]));
144    /// named.set_name("new");
145    /// assert_eq!(named.name(), "new");
146    /// ```
147    #[inline]
148    pub fn set_name(&mut self, name: impl Into<String>) {
149        self.name = name.into();
150    }
151
152    // Values can be directly assigned or mutable methods called on the inner value through DerefMut
153}
154
155/// Transparently delegate read-only methods to the inner `MultiValues` through `Deref`.
156impl Deref for NamedMultiValues {
157    type Target = MultiValues;
158
159    #[inline]
160    fn deref(&self) -> &Self::Target {
161        &self.value
162    }
163}
164
165/// Transparently delegate mutable methods to the inner `MultiValues` through `DerefMut`.
166impl DerefMut for NamedMultiValues {
167    #[inline]
168    fn deref_mut(&mut self) -> &mut Self::Target {
169        &mut self.value
170    }
171}
172
173impl From<NamedValue> for NamedMultiValues {
174    /// Construct `NamedMultiValues` from `NamedValue`
175    ///
176    /// Reuses the name and promotes the single value to a `MultiValues` containing only one element.
177    #[inline]
178    fn from(named: NamedValue) -> Self {
179        // Cannot directly access private fields, use public API and cloning instead
180        let name = named.name().to_string();
181        let value = MultiValues::from((*named).clone());
182        Self { name, value }
183    }
184}