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}