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