Skip to main content

hiver_config/
value.rs

1//! Value module for configuration values
2//! 配置值模块
3//!
4//! # Equivalent to Spring Boot / 等价于 Spring Boot
5//!
6//! - `@Value` annotation - Value extractor
7//! - `SpEL` (Spring Expression Language) support - Placeholder resolution
8
9use crate::ConfigError;
10use serde::{Deserialize, Deserializer, Serialize};
11use std::fmt;
12use std::str::FromStr;
13
14/// Configuration value wrapper
15/// 配置值包装器
16///
17/// Equivalent to Spring's `@Value` annotation support.
18/// 等价于Spring的`@Value`注解支持。
19///
20/// Can hold different types of values and convert between them.
21/// 可以保存不同类型的值并在它们之间转换。
22#[derive(Debug, Clone, Serialize, PartialEq)]
23#[serde(untagged)]
24pub enum Value {
25    /// Null value
26    /// 空值
27    Null,
28
29    /// Boolean value
30    /// 布尔值
31    Bool(bool),
32
33    /// Integer value
34    /// 整数值
35    Integer(i64),
36
37    /// Floating point value
38    /// 浮点数值
39    Float(f64),
40
41    /// String value
42    /// 字符串值
43    String(String),
44
45    /// List value
46    /// 列表值
47    List(Vec<Value>),
48
49    /// Object/map value
50    /// 对象/映射值
51    Object(indexmap::IndexMap<String, Value>),
52}
53
54impl Value {
55    /// Create a null value
56    /// 创建空值
57    pub fn null() -> Self {
58        Value::Null
59    }
60
61    /// Create a boolean value
62    /// 创建布尔值
63    pub fn bool(v: bool) -> Self {
64        Value::Bool(v)
65    }
66
67    /// Create an integer value
68    /// 创建整数值
69    pub fn integer(v: i64) -> Self {
70        Value::Integer(v)
71    }
72
73    /// Create a float value
74    /// 创建浮点数值
75    pub fn float(v: f64) -> Self {
76        Value::Float(v)
77    }
78
79    /// Create a string value
80    /// 创建字符串值
81    pub fn string(v: impl Into<String>) -> Self {
82        Value::String(v.into())
83    }
84
85    /// Create a list value
86    /// 创建列表值
87    pub fn list(v: Vec<Value>) -> Self {
88        Value::List(v)
89    }
90
91    /// Create an object value
92    /// 创建对象值
93    pub fn object(v: indexmap::IndexMap<String, Value>) -> Self {
94        Value::Object(v)
95    }
96
97    /// Check if value is null
98    /// 检查值是否为空
99    pub fn is_null(&self) -> bool {
100        matches!(self, Value::Null)
101    }
102
103    /// Check if value is boolean
104    /// 检查值是否为布尔值
105    pub fn is_bool(&self) -> bool {
106        matches!(self, Value::Bool(_))
107    }
108
109    /// Check if value is integer
110    /// 检查值是否为整数
111    pub fn is_integer(&self) -> bool {
112        matches!(self, Value::Integer(_))
113    }
114
115    /// Check if value is float
116    /// 检查值是否为浮点数
117    pub fn is_float(&self) -> bool {
118        matches!(self, Value::Float(_))
119    }
120
121    /// Check if value is string
122    /// 检查值是否为字符串
123    pub fn is_string(&self) -> bool {
124        matches!(self, Value::String(_))
125    }
126
127    /// Check if value is list
128    /// 检查值是否为列表
129    pub fn is_list(&self) -> bool {
130        matches!(self, Value::List(_))
131    }
132
133    /// Check if value is object
134    /// 检查值是否为对象
135    pub fn is_object(&self) -> bool {
136        matches!(self, Value::Object(_))
137    }
138
139    /// Get as boolean
140    /// 获取布尔值
141    pub fn as_bool(&self) -> Option<bool> {
142        match self {
143            Value::Bool(v) => Some(*v),
144            Value::String(s) => s.parse::<bool>().ok(),
145            Value::Integer(v) => Some(*v != 0),
146            Value::Float(v) => Some(*v != 0.0),
147            _ => None,
148        }
149    }
150
151    /// Get as integer
152    /// 获取整数值
153    pub fn as_i64(&self) -> Option<i64> {
154        match self {
155            Value::Integer(v) => Some(*v),
156            Value::Float(v) => Some(*v as i64),
157            Value::String(s) => s.parse::<i64>().ok(),
158            Value::Bool(v) => Some(*v as i64),
159            _ => None,
160        }
161    }
162
163    /// Get as float
164    /// 获取浮点数值
165    #[allow(clippy::cast_precision_loss)]
166    pub fn as_f64(&self) -> Option<f64> {
167        match self {
168            Value::Float(v) => Some(*v),
169            Value::Integer(v) => Some(*v as f64),
170            Value::String(s) => s.parse::<f64>().ok(),
171            Value::Bool(v) => Some(if *v { 1.0 } else { 0.0 }),
172            _ => None,
173        }
174    }
175
176    /// Get as string
177    /// 获取字符串值
178    pub fn as_str(&self) -> Option<&str> {
179        match self {
180            Value::String(v) => Some(v),
181            Value::Bool(v) => Some(if *v { "true" } else { "false" }),
182            _ => None,
183        }
184    }
185
186    /// Get as string (owned)
187    /// 获取字符串值(拥有所有权)
188    pub fn to_string_value(&self) -> String {
189        match self {
190            Value::String(v) => v.clone(),
191            Value::Bool(v) => (if *v { "true" } else { "false" }).to_string(),
192            Value::Integer(v) => v.to_string(),
193            Value::Float(v) => v.to_string(),
194            Value::Null => "null".to_string(),
195            Value::List(v) => format!("{:?}", v),
196            Value::Object(v) => format!("{:?}", v),
197        }
198    }
199
200    /// Get as list
201    /// 获取列表值
202    pub fn as_list(&self) -> Option<&[Value]> {
203        match self {
204            Value::List(v) => Some(v),
205            _ => None,
206        }
207    }
208
209    /// Get as object
210    /// 获取对象值
211    pub fn as_object(&self) -> Option<&indexmap::IndexMap<String, Value>> {
212        match self {
213            Value::Object(v) => Some(v),
214            _ => None,
215        }
216    }
217
218    /// Convert to a specific type
219    /// 转换为特定类型
220    pub fn into<T>(self) -> Result<T, ConfigError>
221    where
222        T: serde::de::DeserializeOwned,
223    {
224        let debug_str = format!("{:?}", self);
225        let type_name = std::any::type_name::<T>();
226
227        // Special handling for numeric types from strings
228        // This handles cases where properties files store numbers as strings
229        let json_value = match &self {
230            Value::String(s) => {
231                // Try to parse as common numeric types for better UX
232                if type_name.contains("u8")
233                    || type_name.contains("u16")
234                    || type_name.contains("u32")
235                    || type_name.contains("u64")
236                    || type_name.contains("i8")
237                    || type_name.contains("i16")
238                    || type_name.contains("i32")
239                    || type_name.contains("i64")
240                    || type_name.contains("usize")
241                    || type_name.contains("isize")
242                    || type_name.contains("f32")
243                    || type_name.contains("f64")
244                {
245                    // Try to parse as integer or float
246                    if let Ok(i) = s.parse::<i64>() {
247                        serde_json::to_value(i)
248                    } else if let Ok(f) = s.parse::<f64>() {
249                        serde_json::to_value(f)
250                    } else if let Ok(b) = s.parse::<bool>() {
251                        serde_json::to_value(b)
252                    } else {
253                        // Keep as string
254                        serde_json::to_value(&self)
255                    }
256                } else {
257                    serde_json::to_value(&self)
258                }
259            },
260            _ => serde_json::to_value(&self),
261        };
262
263        let json = json_value.map_err(|_e| ConfigError::TypeConversion {
264            key: "unknown".to_string(),
265            expected: type_name.to_string(),
266            value: debug_str.clone(),
267        })?;
268
269        serde_json::from_value(json).map_err(|e| ConfigError::TypeConversion {
270            key: "unknown".to_string(),
271            expected: type_name.to_string(),
272            value: e.to_string(),
273        })
274    }
275}
276
277// From implementations for easy conversion
278impl From<bool> for Value {
279    fn from(v: bool) -> Self {
280        Value::Bool(v)
281    }
282}
283
284impl From<i8> for Value {
285    fn from(v: i8) -> Self {
286        Value::Integer(v as i64)
287    }
288}
289
290impl From<i16> for Value {
291    fn from(v: i16) -> Self {
292        Value::Integer(v as i64)
293    }
294}
295
296impl From<i32> for Value {
297    fn from(v: i32) -> Self {
298        Value::Integer(v as i64)
299    }
300}
301
302impl From<i64> for Value {
303    fn from(v: i64) -> Self {
304        Value::Integer(v)
305    }
306}
307
308impl From<u8> for Value {
309    fn from(v: u8) -> Self {
310        Value::Integer(v as i64)
311    }
312}
313
314impl From<u16> for Value {
315    fn from(v: u16) -> Self {
316        Value::Integer(v as i64)
317    }
318}
319
320impl From<u32> for Value {
321    fn from(v: u32) -> Self {
322        Value::Integer(v as i64)
323    }
324}
325
326impl From<f32> for Value {
327    fn from(v: f32) -> Self {
328        Value::Float(v as f64)
329    }
330}
331
332impl From<f64> for Value {
333    fn from(v: f64) -> Self {
334        Value::Float(v)
335    }
336}
337
338impl From<String> for Value {
339    fn from(v: String) -> Self {
340        Value::String(v)
341    }
342}
343
344impl From<&str> for Value {
345    fn from(v: &str) -> Self {
346        Value::String(v.to_string())
347    }
348}
349
350impl<T> From<Vec<T>> for Value
351where
352    T: Into<Value>,
353{
354    fn from(v: Vec<T>) -> Self {
355        Value::List(v.into_iter().map(Into::into).collect())
356    }
357}
358
359impl<'de> Deserialize<'de> for Value {
360    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
361    where
362        D: Deserializer<'de>,
363    {
364        use serde::de::Error;
365
366        // Use serde_json::Value as intermediate
367        let json_value = serde_json::Value::deserialize(deserializer)?;
368
369        Ok(match json_value {
370            serde_json::Value::Null => Value::Null,
371            serde_json::Value::Bool(v) => Value::Bool(v),
372            serde_json::Value::Number(n) => {
373                if let Some(i) = n.as_i64() {
374                    Value::Integer(i)
375                } else if let Some(f) = n.as_f64() {
376                    Value::Float(f)
377                } else {
378                    return Err(D::Error::custom("Invalid number"));
379                }
380            },
381            serde_json::Value::String(v) => Value::String(v),
382            serde_json::Value::Array(v) => {
383                Value::List(v.into_iter().map(|x| Self::from_json(x)).collect())
384            },
385            serde_json::Value::Object(v) => Value::Object(
386                v.into_iter()
387                    .map(|(k, v)| (k, Self::from_json(v)))
388                    .collect(),
389            ),
390        })
391    }
392}
393
394impl Value {
395    /// Convert from `serde_json::Value`
396    /// `从serde_json::Value转换`
397    fn from_json(json: serde_json::Value) -> Self {
398        match json {
399            serde_json::Value::Null => Value::Null,
400            serde_json::Value::Bool(v) => Value::Bool(v),
401            serde_json::Value::Number(n) => {
402                if let Some(i) = n.as_i64() {
403                    Value::Integer(i)
404                } else if let Some(f) = n.as_f64() {
405                    Value::Float(f)
406                } else {
407                    Value::Null
408                }
409            },
410            serde_json::Value::String(v) => Value::String(v),
411            serde_json::Value::Array(v) => {
412                Value::List(v.into_iter().map(|x| Self::from_json(x)).collect())
413            },
414            serde_json::Value::Object(v) => Value::Object(
415                v.into_iter()
416                    .map(|(k, v)| (k, Self::from_json(v)))
417                    .collect(),
418            ),
419        }
420    }
421}
422
423impl fmt::Display for Value {
424    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
425        match self {
426            Value::Null => write!(f, "null"),
427            Value::Bool(v) => write!(f, "{v}"),
428            Value::Integer(v) => write!(f, "{v}"),
429            Value::Float(v) => write!(f, "{v}"),
430            Value::String(v) => write!(f, "{v}"),
431            Value::List(v) => write!(f, "{:?}", v),
432            Value::Object(v) => write!(f, "{:?}", v),
433        }
434    }
435}
436
437/// Value extractor for @Value annotation equivalent
438/// @Value注解等价物的值提取器
439///
440/// Equivalent to Spring's `@Value` annotation.
441/// 等价于Spring的`@Value`注解。
442///
443/// # Example / 示例
444///
445/// ```rust,no_run,ignore
446/// use hiver_config::ValueExtractor;
447///
448/// // Equivalent to: @Value("${server.port:8080}")
449/// let port: u16 = ValueExtractor::extract("server.port", Some(8080));
450/// ```
451pub struct ValueExtractor;
452
453impl ValueExtractor {
454    /// Extract a value from environment
455    /// 从环境提取值
456    pub fn extract<T>(
457        key: &str,
458        default: Option<T>,
459        env: &crate::Environment,
460    ) -> Result<T, ConfigError>
461    where
462        T: FromStr + serde::de::DeserializeOwned,
463        T::Err: fmt::Display,
464    {
465        if let Some(value) = env.get_property(key)
466            && let Ok(parsed) = value.into::<T>()
467        {
468            return Ok(parsed);
469        }
470
471        default.ok_or_else(|| ConfigError::MissingProperty(key.to_string()))
472    }
473
474    /// Extract string value
475    /// 提取字符串值
476    pub fn extract_string(
477        key: &str,
478        default: Option<&str>,
479        env: &crate::Environment,
480    ) -> Result<String, ConfigError> {
481        if let Some(value) = env.get_property(key)
482            && let Some(s) = value.as_str()
483        {
484            return Ok(s.to_string());
485        }
486
487        default
488            .map(ToString::to_string)
489            .ok_or_else(|| ConfigError::MissingProperty(key.to_string()))
490    }
491
492    /// Extract boolean value
493    /// 提取布尔值
494    pub fn extract_bool(
495        key: &str,
496        default: Option<bool>,
497        env: &crate::Environment,
498    ) -> Result<bool, ConfigError> {
499        if let Some(value) = env.get_property(key)
500            && let Some(b) = value.as_bool()
501        {
502            return Ok(b);
503        }
504
505        default.ok_or_else(|| ConfigError::MissingProperty(key.to_string()))
506    }
507
508    /// Extract integer value
509    /// 提取整数值
510    pub fn extract_int<T>(
511        key: &str,
512        default: Option<T>,
513        env: &crate::Environment,
514    ) -> Result<T, ConfigError>
515    where
516        T: FromStr + serde::de::DeserializeOwned,
517        T::Err: fmt::Display,
518    {
519        if let Some(value) = env.get_property(key)
520            && let Some(i) = value.as_i64()
521            && let Ok(parsed) = i.to_string().parse::<T>()
522        {
523            return Ok(parsed);
524        }
525
526        default.ok_or_else(|| ConfigError::MissingProperty(key.to_string()))
527    }
528
529    /// Parse placeholder expression (e.g., "${key:default}")
530    /// 解析占位符表达式(例如 ${key:default})
531    pub fn parse_placeholder(input: &str) -> (String, Option<String>) {
532        let input = input.trim();
533
534        if !input.starts_with("${") || !input.ends_with('}') {
535            return (input.to_string(), None);
536        }
537
538        let inner = &input[2..input.len() - 1];
539
540        if let Some(colon_pos) = inner.find(':') {
541            let key = inner[..colon_pos].trim().to_string();
542            let default = inner[colon_pos + 1..].trim().to_string();
543            (key, Some(default))
544        } else {
545            (inner.trim().to_string(), None)
546        }
547    }
548
549    /// Resolve placeholder expression with environment
550    /// 使用环境解析占位符表达式
551    pub fn resolve_placeholder(input: &str, env: &crate::Environment) -> String {
552        let (key, default) = Self::parse_placeholder(input);
553
554        if let Some(value) = env.get_property(&key)
555            && let Some(s) = value.as_str()
556        {
557            return s.to_string();
558        }
559
560        default.unwrap_or_default()
561    }
562}
563
564#[cfg(test)]
565mod tests {
566    use super::*;
567    use crate::{Environment, PropertySource};
568
569    // ============================================================
570    // Value creation tests / Value创建测试
571    // ============================================================
572
573    /// Test null value creation
574    /// 测试空值创建
575    #[test]
576    fn test_value_null() {
577        let v = Value::null();
578        assert!(v.is_null());
579        assert!(!v.is_bool());
580        assert!(!v.is_string());
581    }
582
583    /// Test boolean value creation and checking
584    /// 测试布尔值创建和检查
585    #[test]
586    fn test_value_bool() {
587        let t = Value::bool(true);
588        let f = Value::bool(false);
589        assert!(t.is_bool());
590        assert!(f.is_bool());
591        assert_eq!(t.as_bool(), Some(true));
592        assert_eq!(f.as_bool(), Some(false));
593    }
594
595    /// Test integer value creation and checking
596    /// 测试整数值创建和检查
597    #[test]
598    fn test_value_integer() {
599        let v = Value::integer(42);
600        assert!(v.is_integer());
601        assert_eq!(v.as_i64(), Some(42));
602        assert_eq!(v.as_f64(), Some(42.0));
603    }
604
605    /// Test float value creation and checking
606    /// 测试浮点数值创建和检查
607    #[test]
608    fn test_value_float() {
609        let v = Value::float(3.14);
610        assert!(v.is_float());
611        assert_eq!(v.as_f64(), Some(3.14));
612    }
613
614    /// Test string value creation and checking
615    /// 测试字符串值创建和检查
616    #[test]
617    fn test_value_string() {
618        let v = Value::string("hello");
619        assert!(v.is_string());
620        assert_eq!(v.as_str(), Some("hello"));
621    }
622
623    /// Test list value creation and checking
624    /// 测试列表值创建和检查
625    #[test]
626    fn test_value_list() {
627        let v = Value::list(vec![Value::integer(1), Value::integer(2), Value::integer(3)]);
628        assert!(v.is_list());
629        assert_eq!(v.as_list().map(|l| l.len()), Some(3));
630    }
631
632    /// Test object value creation and checking
633    /// 测试对象值创建和检查
634    #[test]
635    fn test_value_object() {
636        let mut map = indexmap::IndexMap::new();
637        map.insert("name".to_string(), Value::string("hiver"));
638        map.insert("port".to_string(), Value::integer(8080));
639        let v = Value::object(map);
640        assert!(v.is_object());
641        assert_eq!(v.as_object().map(|o| o.len()), Some(2));
642    }
643
644    // ============================================================
645    // Type conversion tests / 类型转换测试
646    // ============================================================
647
648    /// Test boolean type coercion from various Value types
649    /// 测试从各种Value类型强制转换为布尔值
650    #[test]
651    fn test_as_bool_coercion() {
652        // String "true"/"false" -> bool
653        assert_eq!(Value::string("true").as_bool(), Some(true));
654        assert_eq!(Value::string("false").as_bool(), Some(false));
655
656        // Integer 0/non-zero -> bool
657        assert_eq!(Value::integer(0).as_bool(), Some(false));
658        assert_eq!(Value::integer(1).as_bool(), Some(true));
659        assert_eq!(Value::integer(-1).as_bool(), Some(true));
660
661        // Float 0.0/non-zero -> bool
662        assert_eq!(Value::float(0.0).as_bool(), Some(false));
663        assert_eq!(Value::float(1.5).as_bool(), Some(true));
664
665        // Null and List cannot convert to bool
666        assert_eq!(Value::null().as_bool(), None);
667        assert_eq!(Value::list(vec![]).as_bool(), None);
668    }
669
670    /// Test integer type coercion from various Value types
671    /// 测试从各种Value类型强制转换为整数
672    #[test]
673    fn test_as_i64_coercion() {
674        assert_eq!(Value::integer(42).as_i64(), Some(42));
675        assert_eq!(Value::float(3.9).as_i64(), Some(3));
676        assert_eq!(Value::string("100").as_i64(), Some(100));
677        assert_eq!(Value::bool(true).as_i64(), Some(1));
678        assert_eq!(Value::bool(false).as_i64(), Some(0));
679        assert_eq!(Value::null().as_i64(), None);
680        assert_eq!(Value::string("not_a_number").as_i64(), None);
681    }
682
683    /// Test float type coercion from various Value types
684    /// 测试从各种Value类型强制转换为浮点数
685    #[test]
686    fn test_as_f64_coercion() {
687        assert_eq!(Value::float(2.5).as_f64(), Some(2.5));
688        assert_eq!(Value::integer(10).as_f64(), Some(10.0));
689        assert_eq!(Value::string("3.14").as_f64(), Some(3.14));
690        assert_eq!(Value::bool(true).as_f64(), Some(1.0));
691        assert_eq!(Value::bool(false).as_f64(), Some(0.0));
692        assert_eq!(Value::null().as_f64(), None);
693    }
694
695    /// Test string extraction from Value types
696    /// 测试从Value类型提取字符串
697    #[test]
698    fn test_as_str_variants() {
699        assert_eq!(Value::string("hello").as_str(), Some("hello"));
700        assert_eq!(Value::bool(true).as_str(), Some("true"));
701        assert_eq!(Value::bool(false).as_str(), Some("false"));
702        assert_eq!(Value::integer(42).as_str(), None);
703        assert_eq!(Value::null().as_str(), None);
704    }
705
706    /// Test to_string_value for all Value variants
707    /// 测试所有Value变体的to_string_value
708    #[test]
709    fn test_to_string_value() {
710        assert_eq!(Value::null().to_string_value(), "null");
711        assert_eq!(Value::bool(true).to_string_value(), "true");
712        assert_eq!(Value::bool(false).to_string_value(), "false");
713        assert_eq!(Value::integer(42).to_string_value(), "42");
714        assert_eq!(Value::float(3.14).to_string_value(), "3.14");
715        assert_eq!(Value::string("hello".to_string()).to_string_value(), "hello");
716    }
717
718    /// Test into<T> for numeric deserialization from string values
719    /// 测试从字符串值反序列化为数值类型的into<T>
720    #[test]
721    fn test_into_numeric_from_string() {
722        // String holding a number should parse into numeric types
723        let v = Value::string("42");
724        assert_eq!(v.clone().into::<i32>().unwrap(), 42i32);
725        assert_eq!(v.clone().into::<u16>().unwrap(), 42u16);
726        assert_eq!(v.clone().into::<i64>().unwrap(), 42i64);
727    }
728
729    /// Test into<T> for string deserialization
730    /// 测试字符串反序列化的into<T>
731    #[test]
732    fn test_into_string() {
733        let v = Value::string("hello");
734        let result: String = v.into::<String>().unwrap();
735        assert_eq!(result, "hello");
736    }
737
738    /// Test into<T> failure on incompatible type
739    /// 测试不兼容类型的into<T>失败
740    #[test]
741    fn test_into_failure() {
742        let v = Value::string("not_a_number");
743        let result = v.into::<i32>();
744        assert!(result.is_err());
745    }
746
747    // ============================================================
748    // From<T> implementation tests / From<T>实现测试
749    // ============================================================
750
751    /// Test From<bool> for Value
752    /// 测试Value的From<bool>
753    #[test]
754    fn test_from_bool() {
755        let v: Value = true.into();
756        assert!(v.is_bool());
757        assert_eq!(v.as_bool(), Some(true));
758    }
759
760    /// Test From integer types for Value
761    /// 测试Value的各种整数类型From实现
762    #[test]
763    fn test_from_integers() {
764        let v8: Value = 8i8.into();
765        let v16: Value = 16i16.into();
766        let v32: Value = 32i32.into();
767        let v64: Value = 64i64.into();
768        let vu8: Value = 8u8.into();
769        let vu16: Value = 16u16.into();
770        let vu32: Value = 32u32.into();
771
772        assert!(v8.is_integer());
773        assert_eq!(v8.as_i64(), Some(8));
774        assert!(v16.is_integer());
775        assert_eq!(v16.as_i64(), Some(16));
776        assert!(v32.is_integer());
777        assert_eq!(v32.as_i64(), Some(32));
778        assert!(v64.is_integer());
779        assert_eq!(v64.as_i64(), Some(64));
780        assert!(vu8.is_integer());
781        assert_eq!(vu8.as_i64(), Some(8));
782        assert!(vu16.is_integer());
783        assert_eq!(vu16.as_i64(), Some(16));
784        assert!(vu32.is_integer());
785        assert_eq!(vu32.as_i64(), Some(32));
786    }
787
788    /// Test From float types for Value
789    /// 测试Value的浮点类型From实现
790    #[test]
791    fn test_from_floats() {
792        let vf32: Value = 1.5f32.into();
793        let vf64: Value = 2.5f64.into();
794        assert!(vf32.is_float());
795        assert!(vf64.is_float());
796    }
797
798    /// Test From string types for Value
799    /// 测试Value的字符串类型From实现
800    #[test]
801    fn test_from_strings() {
802        let v1: Value = "hello".into();
803        let v2: Value = String::from("world").into();
804        assert!(v1.is_string());
805        assert!(v2.is_string());
806        assert_eq!(v1.as_str(), Some("hello"));
807        assert_eq!(v2.as_str(), Some("world"));
808    }
809
810    /// Test From Vec for Value (list conversion)
811    /// 测试Value的Vec From实现(列表转换)
812    #[test]
813    fn test_from_vec() {
814        let v: Value = vec![1i32, 2, 3].into();
815        assert!(v.is_list());
816        assert_eq!(v.as_list().map(|l| l.len()), Some(3));
817    }
818
819    // ============================================================
820    // Display and Serde tests / Display和序列化测试
821    // ============================================================
822
823    /// Test Display trait for Value
824    /// 测试Value的Display trait
825    #[test]
826    fn test_display() {
827        assert_eq!(format!("{}", Value::null()), "null");
828        assert_eq!(format!("{}", Value::bool(true)), "true");
829        assert_eq!(format!("{}", Value::integer(42)), "42");
830        assert_eq!(format!("{}", Value::float(1.5)), "1.5");
831        assert_eq!(format!("{}", Value::string("hello")), "hello");
832    }
833
834    /// Test Serialize and Deserialize round-trip for Value
835    /// 测试Value的序列化和反序列化往返
836    #[test]
837    fn test_serde_roundtrip() {
838        let original = Value::string("test_value");
839        let json = serde_json::to_string(&original).unwrap();
840        let deserialized: Value = serde_json::from_str(&json).unwrap();
841        assert_eq!(original, deserialized);
842    }
843
844    /// Test Deserialize JSON null into Value
845    /// 测试将JSON null反序列化为Value
846    #[test]
847    fn test_deserialize_json_null() {
848        let v: Value = serde_json::from_str("null").unwrap();
849        assert!(v.is_null());
850    }
851
852    /// Test Deserialize JSON number into Value
853    /// 测试将JSON数字反序列化为Value
854    #[test]
855    fn test_deserialize_json_number() {
856        let vi: Value = serde_json::from_str("42").unwrap();
857        assert!(vi.is_integer());
858        assert_eq!(vi.as_i64(), Some(42));
859
860        let vf: Value = serde_json::from_str("3.14").unwrap();
861        assert!(vf.is_float());
862    }
863
864    /// Test Deserialize JSON object into Value
865    /// 测试将JSON对象反序列化为Value
866    #[test]
867    fn test_deserialize_json_object() {
868        let v: Value = serde_json::from_str(r#"{"key": "value", "num": 1}"#).unwrap();
869        assert!(v.is_object());
870        let obj = v.as_object().unwrap();
871        assert_eq!(obj.get("key").unwrap().as_str(), Some("value"));
872        assert_eq!(obj.get("num").unwrap().as_i64(), Some(1));
873    }
874
875    /// Test Deserialize JSON array into Value
876    /// 测试将JSON数组反序列化为Value
877    #[test]
878    fn test_deserialize_json_array() {
879        let v: Value = serde_json::from_str("[1, true, \"hello\"]").unwrap();
880        assert!(v.is_list());
881        let list = v.as_list().unwrap();
882        assert_eq!(list.len(), 3);
883        assert_eq!(list[0].as_i64(), Some(1));
884        assert_eq!(list[1].as_bool(), Some(true));
885        assert_eq!(list[2].as_str(), Some("hello"));
886    }
887
888    // ============================================================
889    // ValueExtractor tests / 值提取器测试
890    // ============================================================
891
892    /// Test parse_placeholder with default value
893    /// 测试带默认值的占位符解析
894    #[test]
895    fn test_parse_placeholder_with_default() {
896        let (key, default) = ValueExtractor::parse_placeholder("${server.port:8080}");
897        assert_eq!(key, "server.port");
898        assert_eq!(default, Some("8080".to_string()));
899    }
900
901    /// Test parse_placeholder without default value
902    /// 测试不带默认值的占位符解析
903    #[test]
904    fn test_parse_placeholder_without_default() {
905        let (key, default) = ValueExtractor::parse_placeholder("${server.port}");
906        assert_eq!(key, "server.port");
907        assert_eq!(default, None);
908    }
909
910    /// Test parse_placeholder on non-placeholder string
911    /// 测试非占位符字符串的解析
912    #[test]
913    fn test_parse_placeholder_non_placeholder() {
914        let (key, default) = ValueExtractor::parse_placeholder("just a string");
915        assert_eq!(key, "just a string");
916        assert_eq!(default, None);
917    }
918
919    /// Test parse_placeholder with whitespace
920    /// 测试带空格的占位符解析
921    #[test]
922    fn test_parse_placeholder_whitespace() {
923        let (key, default) = ValueExtractor::parse_placeholder("  ${ server.host : localhost }  ");
924        assert_eq!(key, "server.host");
925        assert_eq!(default, Some("localhost".to_string()));
926    }
927
928    /// Test resolve_placeholder returns value from environment
929    /// 测试resolve_placeholder从环境返回值
930    #[test]
931    fn test_resolve_placeholder_from_env() {
932        use crate::{Environment, PropertySource};
933        let env = Environment::new();
934        let mut source = PropertySource::new("test");
935        source.put("app.name", Value::string("hiver"));
936        env.add_property_source(source);
937
938        let result = ValueExtractor::resolve_placeholder("${app.name}", &env);
939        assert_eq!(result, "hiver");
940    }
941
942    /// Test resolve_placeholder falls back to default
943    /// 测试resolve_placeholder回退到默认值
944    #[test]
945    fn test_resolve_placeholder_default() {
946        let env = Environment::new();
947        let result = ValueExtractor::resolve_placeholder("${missing.key:fallback}", &env);
948        assert_eq!(result, "fallback");
949    }
950
951    /// Test resolve_placeholder returns empty when no default and key missing
952    /// 测试无默认值且键缺失时返回空字符串
953    #[test]
954    fn test_resolve_placeholder_no_default_missing_key() {
955        let env = Environment::new();
956        let result = ValueExtractor::resolve_placeholder("${missing.key}", &env);
957        assert_eq!(result, "");
958    }
959
960    /// Test extract_string from environment
961    /// 测试从环境提取字符串值
962    #[test]
963    fn test_extract_string_present() {
964        let env = Environment::new();
965        let mut source = PropertySource::new("test");
966        source.put("greeting", Value::string("hello"));
967        env.add_property_source(source);
968
969        let result = ValueExtractor::extract_string("greeting", None, &env).unwrap();
970        assert_eq!(result, "hello");
971    }
972
973    /// Test extract_string falls back to default
974    /// 测试extract_string回退到默认值
975    #[test]
976    fn test_extract_string_default() {
977        let env = Environment::new();
978        let result = ValueExtractor::extract_string("missing", Some("default_val"), &env).unwrap();
979        assert_eq!(result, "default_val");
980    }
981
982    /// Test extract_string error when missing without default
983    /// 测试缺失且无默认值时extract_string返回错误
984    #[test]
985    fn test_extract_string_missing_error() {
986        let env = Environment::new();
987        let result = ValueExtractor::extract_string("nonexistent", None, &env);
988        assert!(result.is_err());
989    }
990
991    /// Test extract_bool from environment
992    /// 测试从环境提取布尔值
993    #[test]
994    fn test_extract_bool() {
995        let env = Environment::new();
996        let mut source = PropertySource::new("test");
997        source.put("debug", Value::bool(true));
998        env.add_property_source(source);
999
1000        let result = ValueExtractor::extract_bool("debug", None, &env).unwrap();
1001        assert!(result);
1002    }
1003
1004    /// Test extract_bool default value
1005    /// 测试extract_bool默认值
1006    #[test]
1007    fn test_extract_bool_default() {
1008        let env = Environment::new();
1009        let result = ValueExtractor::extract_bool("missing", Some(false), &env).unwrap();
1010        assert!(!result);
1011    }
1012
1013    /// Test extract_int from environment
1014    /// 测试从环境提取整数值
1015    #[test]
1016    fn test_extract_int() {
1017        let env = Environment::new();
1018        let mut source = PropertySource::new("test");
1019        source.put("port", Value::integer(9090));
1020        env.add_property_source(source);
1021
1022        let result = ValueExtractor::extract_int::<i32>("port", None, &env).unwrap();
1023        assert_eq!(result, 9090);
1024    }
1025
1026    /// Test extract_int default value
1027    /// 测试extract_int默认值
1028    #[test]
1029    fn test_extract_int_default() {
1030        let env = Environment::new();
1031        let result = ValueExtractor::extract_int::<i32>("missing", Some(8080), &env).unwrap();
1032        assert_eq!(result, 8080);
1033    }
1034
1035    /// Test generic extract with typed Value
1036    /// 测试泛型extract方法
1037    #[test]
1038    fn test_extract_generic() {
1039        let env = Environment::new();
1040        let mut source = PropertySource::new("test");
1041        source.put("count", Value::integer(7));
1042        env.add_property_source(source);
1043
1044        let result = ValueExtractor::extract("count", Some(0i32), &env).unwrap();
1045        assert_eq!(result, 7);
1046    }
1047
1048    /// Test extract with missing key uses default
1049    /// 测试键缺失时extract使用默认值
1050    #[test]
1051    fn test_extract_generic_default() {
1052        let env = Environment::new();
1053        let result = ValueExtractor::extract("absent", Some(99i32), &env).unwrap();
1054        assert_eq!(result, 99);
1055    }
1056
1057    /// Test extract with missing key and no default returns error
1058    /// 测试键缺失且无默认值时extract返回错误
1059    #[test]
1060    fn test_extract_generic_missing_no_default() {
1061        let env = Environment::new();
1062        let result: Result<i32, _> = ValueExtractor::extract("absent", None, &env);
1063        assert!(result.is_err());
1064    }
1065}