Skip to main content

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}