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}