Skip to main content

qubit_config/
property.rs

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