prism3_value/named_multi_values.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism 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 pub fn new(name: impl Into<String>, value: MultiValues) -> Self {
100 Self {
101 name: name.into(),
102 value,
103 }
104 }
105
106 /// Get a reference to the name
107 ///
108 /// # Returns
109 ///
110 /// Returns a string slice of the name
111 ///
112 /// # Example
113 ///
114 /// ```rust
115 /// use common_rs::util::value::{NamedMultiValues, MultiValues};
116 ///
117 /// let named = NamedMultiValues::new("items", MultiValues::Int32(vec![1, 2, 3]));
118 /// assert_eq!(named.name(), "items");
119 /// ```
120 pub fn name(&self) -> &str {
121 &self.name
122 }
123
124 // Methods of MultiValues are forwarded through Deref/DerefMut
125
126 /// Set a new name
127 ///
128 /// # Parameters
129 ///
130 /// * `name` - The new name
131 ///
132 /// # Returns
133 ///
134 /// No return value
135 ///
136 /// # Example
137 ///
138 /// ```rust
139 /// use common_rs::util::value::{NamedMultiValues, MultiValues};
140 ///
141 /// let mut named = NamedMultiValues::new("old", MultiValues::Bool(vec![true]));
142 /// named.set_name("new");
143 /// assert_eq!(named.name(), "new");
144 /// ```
145 pub fn set_name(&mut self, name: impl Into<String>) {
146 self.name = name.into();
147 }
148
149 // Values can be directly assigned or mutable methods called on the inner value through DerefMut
150}
151
152/// Transparently delegate read-only methods to the inner `MultiValues` through `Deref`.
153impl Deref for NamedMultiValues {
154 type Target = MultiValues;
155
156 fn deref(&self) -> &Self::Target {
157 &self.value
158 }
159}
160
161/// Transparently delegate mutable methods to the inner `MultiValues` through `DerefMut`.
162impl DerefMut for NamedMultiValues {
163 fn deref_mut(&mut self) -> &mut Self::Target {
164 &mut self.value
165 }
166}
167
168impl From<NamedValue> for NamedMultiValues {
169 /// Construct `NamedMultiValues` from `NamedValue`
170 ///
171 /// Reuses the name and promotes the single value to a `MultiValues` containing only one element.
172 fn from(named: NamedValue) -> Self {
173 // Cannot directly access private fields, use public API and cloning instead
174 let name = named.name().to_string();
175 let value = MultiValues::from((*named).clone());
176 Self { name, value }
177 }
178}