qubit_config/property.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Configuration Property
10//!
11//! Defines the property structure for configuration items, including name, value, description, and other information.
12//!
13//! # Author
14//!
15//! Haixing Hu
16
17use serde::{Deserialize, Serialize};
18use std::ops::{Deref, DerefMut};
19
20use qubit_common::DataType;
21use qubit_value::MultiValues;
22
23/// Configuration Property
24///
25/// Represents a configuration item, containing name, value, description, and whether it's a final value.
26///
27/// # Features
28///
29/// - Supports multi-value configuration
30/// - Supports description information
31/// - Supports final value marking (final properties cannot be overridden)
32/// - Supports serialization and deserialization
33///
34/// # Important Limitations of Generic set/add Methods
35///
36/// **`u8` type does not support generic `set()` and `add()` methods**. See `MultiValues` documentation for details.
37///
38/// For `u8` type, use dedicated methods:
39///
40/// ```rust,ignore
41/// use qubit_config::Property;
42///
43/// let mut prop = Property::new("byte_value");
44///
45/// // ✅ Use dedicated methods to set u8
46/// prop.set_uint8(42).unwrap();
47/// prop.add_uint8(128).unwrap();
48///
49/// // ❌ Generic methods not supported
50/// // prop.set(42u8).unwrap(); // Compile error
51/// ```
52///
53/// # Examples
54///
55/// ```rust,ignore
56/// use qubit_config::Property;
57///
58/// let mut prop = Property::new("port");
59/// prop.set(8080).unwrap(); // Generic method, type auto-inferred
60/// prop.set_description(Some("Server port".to_string()));
61///
62/// assert_eq!(prop.name(), "port");
63/// assert_eq!(prop.count(), 1);
64/// ```
65///
66/// # Author
67///
68/// Haixing Hu
69///
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
71pub struct Property {
72 /// Property name
73 name: String,
74 /// Property value
75 value: MultiValues,
76 /// Property description
77 description: Option<String>,
78 /// Whether this is a final value (cannot be overridden)
79 is_final: bool,
80}
81
82impl Property {
83 /// Creates a new property
84 ///
85 /// Creates an empty property with an initial value of an empty i32 list.
86 ///
87 /// # Parameters
88 ///
89 /// * `name` - Property name
90 ///
91 /// # Returns
92 ///
93 /// Returns a new property instance
94 ///
95 /// # Examples
96 ///
97 /// ```rust,ignore
98 /// use common_rs::util::config::Property;
99 ///
100 /// let prop = Property::new("server.port");
101 /// assert_eq!(prop.name(), "server.port");
102 /// assert!(prop.is_empty());
103 /// ```
104 pub fn new(name: impl Into<String>) -> Self {
105 Self {
106 name: name.into(),
107 value: MultiValues::Empty(DataType::Int32),
108 description: None,
109 is_final: false,
110 }
111 }
112
113 /// Creates a property with a value
114 ///
115 /// # Parameters
116 ///
117 /// * `name` - Property name
118 /// * `value` - Property value
119 ///
120 /// # Returns
121 ///
122 /// Returns a new property instance
123 ///
124 /// # Examples
125 ///
126 /// ```rust,ignore
127 /// use qubit_config::Property;
128 /// use qubit_value::MultiValues;
129 ///
130 /// let prop = Property::with_value("port", MultiValues::Int32(vec![8080]));
131 /// assert_eq!(prop.name(), "port");
132 /// assert_eq!(prop.count(), 1);
133 /// ```
134 pub fn with_value(name: impl Into<String>, value: MultiValues) -> Self {
135 Self {
136 name: name.into(),
137 value,
138 description: None,
139 is_final: false,
140 }
141 }
142
143 /// Gets the property name
144 ///
145 /// # Returns
146 ///
147 /// Returns the property name as a string slice
148 pub fn name(&self) -> &str {
149 &self.name
150 }
151
152 /// Gets a reference to the property value
153 ///
154 /// # Returns
155 ///
156 /// Returns a reference to the property value
157 pub fn value(&self) -> &MultiValues {
158 &self.value
159 }
160
161 /// Gets a mutable reference to the property value
162 ///
163 /// # Returns
164 ///
165 /// Returns a mutable reference to the property value
166 pub fn value_mut(&mut self) -> &mut MultiValues {
167 &mut self.value
168 }
169
170 /// Sets the property value
171 ///
172 /// # Parameters
173 ///
174 /// * `value` - New property value
175 pub fn set_value(&mut self, value: MultiValues) {
176 self.value = value;
177 }
178
179 /// Gets the property description
180 ///
181 /// # Returns
182 ///
183 /// Returns the property description as Option
184 pub fn description(&self) -> Option<&str> {
185 self.description.as_deref()
186 }
187
188 /// Sets the property description
189 ///
190 /// # Parameters
191 ///
192 /// * `description` - Property description
193 pub fn set_description(&mut self, description: Option<String>) {
194 self.description = description;
195 }
196
197 /// Checks if this is a final value
198 ///
199 /// # Returns
200 ///
201 /// Returns `true` if the property is final
202 pub fn is_final(&self) -> bool {
203 self.is_final
204 }
205
206 /// Sets whether this is a final value
207 ///
208 /// # Parameters
209 ///
210 /// * `is_final` - Whether this is final
211 pub fn set_final(&mut self, is_final: bool) {
212 self.is_final = is_final;
213 }
214
215 /// Gets the data type
216 ///
217 /// # Returns
218 ///
219 /// Returns the data type of the property value
220 pub fn data_type(&self) -> DataType {
221 self.value.data_type()
222 }
223
224 /// Gets the number of values
225 ///
226 /// # Returns
227 ///
228 /// Returns the number of values in the property
229 pub fn count(&self) -> usize {
230 self.value.count()
231 }
232
233 /// Checks if the property is empty
234 ///
235 /// # Returns
236 ///
237 /// Returns `true` if the property contains no values
238 pub fn is_empty(&self) -> bool {
239 self.value.is_empty()
240 }
241
242 /// Clears the property value
243 ///
244 /// Clears all values in the property but keeps type information
245 pub fn clear(&mut self) {
246 self.value.clear();
247 }
248}
249
250impl Deref for Property {
251 type Target = MultiValues;
252
253 /// Dereferences to MultiValues
254 ///
255 /// Allows direct access to all MultiValues methods
256 fn deref(&self) -> &Self::Target {
257 &self.value
258 }
259}
260
261impl DerefMut for Property {
262 /// Mutably dereferences to MultiValues
263 ///
264 /// Allows direct mutable access to all MultiValues methods
265 fn deref_mut(&mut self) -> &mut Self::Target {
266 &mut self.value
267 }
268}