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}