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}