Skip to main content

sz_orm_core/
accessors.rs

1//! Accessors / Mutators + Attribute Casting
2//!
3//! 对应文档 6.8 节改进项 22(Accessors/Mutators)+ 23(Attribute Casting)。
4//!
5//! # 核心概念
6//!
7//! - **Accessor**:字段读取器(getter),从存储值转换为展示值
8//! - **Mutator**:字段设置器(setter),从输入值转换为存储值
9//! - **AttributeCaster**:字段类型转换器(数据库 <-> Rust 类型)
10//! - **AccessorRegistry**:Accessor/Mutator 注册中心
11//!
12//! # 设计灵感
13//!
14//! - Laravel Eloquent `getCasts()` / `mutators` / `accessors`
15//! - Doctrine `@Column(type="...")` 类型转换
16//! - Rails ActiveRecord `serialize` / `attr_accessor`
17//!
18//! # 使用示例
19//!
20//! ```no_run
21//! use sz_orm_core::accessors::{
22//!     AccessorRegistry, AttributeCaster, CastType,
23//! };
24//! use sz_orm_core::Value;
25//!
26//! let mut registry = AccessorRegistry::new();
27//!
28//! // 注册 is_admin 字段:数据库存 SMALLINT,读出时转为 bool
29//! registry.register_cast("is_admin", CastType::Boolean);
30//!
31//! // 注册 settings 字段:数据库存 TEXT,读出时解析为 JSON
32//! registry.register_cast("settings", CastType::Json);
33//!
34//! // 应用 casting(从数据库读出)
35//! let stored = Value::I64(1);
36//! let casted = registry.cast_read("is_admin", stored);
37//! assert_eq!(casted, Value::Bool(true));
38//! ```
39
40use crate::value::Value;
41use std::collections::HashMap;
42
43// ============================================================================
44// CastType — 字段类型转换枚举
45// ============================================================================
46
47/// 字段类型转换枚举
48///
49/// 定义字段在数据库存储与 Rust 类型之间的转换方式。
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51pub enum CastType {
52    /// 转 i64(适用于 INTEGER/BIGINT → i64)
53    Integer,
54    /// 转 f64(适用于 FLOAT/DOUBLE → f64)
55    Float,
56    /// 转布尔(适用于 SMALLINT(0/1)/CHAR('Y'/'N') → bool)
57    Boolean,
58    /// 转字符串(适用于 TEXT/VARCHAR → String)
59    String,
60    /// 转 JSON(适用于 TEXT → JSON 反序列化)
61    Json,
62    /// 转 DateTime(适用于 TIMESTAMP → ISO8601 字符串)
63    DateTime,
64    /// 转 Date(适用于 DATE → YYYY-MM-DD 字符串)
65    Date,
66    /// 转 Time(适用于 TIME → HH:MM:SS 字符串)
67    Time,
68    /// 转 Bytes(适用于 BLOB → `Vec<u8>`)
69    Bytes,
70    /// 转 Array(适用于 JSON 数组 → `Vec<Value>`)
71    Array,
72}
73
74impl CastType {
75    /// 类型名称(用于错误信息)
76    pub fn name(&self) -> &'static str {
77        match self {
78            CastType::Integer => "integer",
79            CastType::Float => "float",
80            CastType::Boolean => "boolean",
81            CastType::String => "string",
82            CastType::Json => "json",
83            CastType::DateTime => "datetime",
84            CastType::Date => "date",
85            CastType::Time => "time",
86            CastType::Bytes => "bytes",
87            CastType::Array => "array",
88        }
89    }
90}
91
92// ============================================================================
93// Accessor / Mutator trait — 自定义字段读写器
94// ============================================================================
95
96/// 自定义字段读取器(Accessor / Getter)
97///
98/// 在从数据库读取字段值后调用,将存储值转换为展示值。
99pub trait Accessor: Send + Sync {
100    /// 字段名
101    fn field(&self) -> &str;
102
103    /// 读取转换:将存储值转换为展示值
104    fn read(&self, value: Value) -> Value;
105}
106
107/// 自定义字段设置器(Mutator / Setter)
108///
109/// 在写入数据库前调用,将输入值转换为存储值。
110pub trait Mutator: Send + Sync {
111    /// 字段名
112    fn field(&self) -> &str;
113
114    /// 写入转换:将输入值转换为存储值
115    fn write(&self, value: Value) -> Value;
116}
117
118// ============================================================================
119// 闭包风格的 Accessor / Mutator
120// ============================================================================
121
122/// 闭包风格 Accessor
123pub struct ClosureAccessor {
124    /// 字段名
125    pub field_name: String,
126    /// 读取转换闭包
127    pub reader: Box<dyn Fn(Value) -> Value + Send + Sync>,
128}
129
130impl ClosureAccessor {
131    /// 创建闭包 Accessor
132    pub fn new(
133        field: impl Into<String>,
134        reader: impl Fn(Value) -> Value + Send + Sync + 'static,
135    ) -> Self {
136        Self {
137            field_name: field.into(),
138            reader: Box::new(reader),
139        }
140    }
141}
142
143impl Accessor for ClosureAccessor {
144    fn field(&self) -> &str {
145        &self.field_name
146    }
147
148    fn read(&self, value: Value) -> Value {
149        (self.reader)(value)
150    }
151}
152
153/// 闭包风格 Mutator
154pub struct ClosureMutator {
155    /// 字段名
156    pub field_name: String,
157    /// 写入转换闭包
158    pub writer: Box<dyn Fn(Value) -> Value + Send + Sync>,
159}
160
161impl ClosureMutator {
162    /// 创建闭包 Mutator
163    pub fn new(
164        field: impl Into<String>,
165        writer: impl Fn(Value) -> Value + Send + Sync + 'static,
166    ) -> Self {
167        Self {
168            field_name: field.into(),
169            writer: Box::new(writer),
170        }
171    }
172}
173
174impl Mutator for ClosureMutator {
175    fn field(&self) -> &str {
176        &self.field_name
177    }
178
179    fn write(&self, value: Value) -> Value {
180        (self.writer)(value)
181    }
182}
183
184// ============================================================================
185// AttributeCaster — 类型转换器(数据库 <-> Rust 类型)
186// ============================================================================
187
188/// 类型转换器
189///
190/// 根据 `CastType` 将 Value 在数据库存储类型与 Rust 业务类型之间转换。
191pub struct AttributeCaster;
192
193impl AttributeCaster {
194    /// 从数据库读出时的类型转换(db → rust)
195    pub fn cast_read(value: Value, target: CastType) -> Value {
196        match target {
197            CastType::Integer => Self::to_integer(value),
198            CastType::Float => Self::to_float(value),
199            CastType::Boolean => Self::to_boolean(value),
200            CastType::String => Self::to_string_value(value),
201            CastType::Json => Self::to_json(value),
202            CastType::DateTime => Self::to_datetime(value),
203            CastType::Date => Self::to_date(value),
204            CastType::Time => Self::to_time(value),
205            CastType::Bytes => Self::to_bytes(value),
206            CastType::Array => Self::to_array(value),
207        }
208    }
209
210    /// 写入数据库时的类型转换(rust → db)
211    pub fn cast_write(value: Value, target: CastType) -> Value {
212        match target {
213            CastType::Integer => Self::to_integer(value),
214            CastType::Float => Self::to_float(value),
215            CastType::Boolean => Self::to_boolean_storage(value),
216            CastType::String => Self::to_string_value(value),
217            CastType::Json => Self::to_json_storage(value),
218            CastType::DateTime => Self::to_datetime_storage(value),
219            CastType::Date => Self::to_date_storage(value),
220            CastType::Time => Self::to_time_storage(value),
221            CastType::Bytes => Self::to_bytes(value),
222            CastType::Array => Self::to_array_storage(value),
223        }
224    }
225
226    // ===== 转换函数 =====
227
228    fn to_integer(value: Value) -> Value {
229        match value {
230            Value::I64(_) | Value::I32(_) | Value::I8(_) | Value::I16(_) => value,
231            Value::U32(v) => Value::I64(v as i64),
232            Value::U64(v) => Value::I64(v as i64),
233            Value::U8(v) => Value::I64(v as i64),
234            Value::U16(v) => Value::I64(v as i64),
235            Value::F32(v) => Value::I64(v as i64),
236            Value::F64(v) => Value::I64(v as i64),
237            Value::Bool(b) => Value::I64(if b { 1 } else { 0 }),
238            Value::String(s) => {
239                if let Ok(n) = s.trim().parse::<i64>() {
240                    Value::I64(n)
241                } else {
242                    Value::Null
243                }
244            }
245            Value::Null => Value::Null,
246            _ => Value::Null,
247        }
248    }
249
250    fn to_float(value: Value) -> Value {
251        match value {
252            Value::F32(_) | Value::F64(_) => value,
253            Value::I64(v) => Value::F64(v as f64),
254            Value::I32(v) => Value::F64(v as f64),
255            Value::I8(v) => Value::F64(v as f64),
256            Value::I16(v) => Value::F64(v as f64),
257            Value::U32(v) => Value::F64(v as f64),
258            Value::U64(v) => Value::F64(v as f64),
259            Value::U8(v) => Value::F64(v as f64),
260            Value::U16(v) => Value::F64(v as f64),
261            Value::Bool(b) => Value::F64(if b { 1.0 } else { 0.0 }),
262            Value::String(s) => {
263                if let Ok(n) = s.trim().parse::<f64>() {
264                    Value::F64(n)
265                } else {
266                    Value::Null
267                }
268            }
269            Value::Null => Value::Null,
270            _ => Value::Null,
271        }
272    }
273
274    fn to_boolean(value: Value) -> Value {
275        match value {
276            Value::Bool(_) => value,
277            Value::I64(v) => Value::Bool(v != 0),
278            Value::I32(v) => Value::Bool(v != 0),
279            Value::I8(v) => Value::Bool(v != 0),
280            Value::I16(v) => Value::Bool(v != 0),
281            Value::U32(v) => Value::Bool(v != 0),
282            Value::U64(v) => Value::Bool(v != 0),
283            Value::U8(v) => Value::Bool(v != 0),
284            Value::U16(v) => Value::Bool(v != 0),
285            Value::F32(v) => Value::Bool(v != 0.0),
286            Value::F64(v) => Value::Bool(v != 0.0),
287            Value::String(s) => {
288                let lower = s.trim().to_lowercase();
289                Value::Bool(matches!(
290                    lower.as_str(),
291                    "1" | "true" | "yes" | "on" | "y" | "t"
292                ))
293            }
294            Value::Null => Value::Null,
295            _ => Value::Null,
296        }
297    }
298
299    fn to_boolean_storage(value: Value) -> Value {
300        match value {
301            Value::Bool(b) => Value::I64(if b { 1 } else { 0 }),
302            Value::I64(_) | Value::I32(_) | Value::I8(_) | Value::I16(_) => value,
303            Value::U32(v) => Value::I64(if v != 0 { 1 } else { 0 }),
304            Value::U64(v) => Value::I64(if v != 0 { 1 } else { 0 }),
305            Value::U8(v) => Value::I64(if v != 0 { 1 } else { 0 }),
306            Value::U16(v) => Value::I64(if v != 0 { 1 } else { 0 }),
307            Value::F32(v) => Value::I64(if v != 0.0 { 1 } else { 0 }),
308            Value::F64(v) => Value::I64(if v != 0.0 { 1 } else { 0 }),
309            Value::String(s) => {
310                let lower = s.trim().to_lowercase();
311                Value::I64(
312                    if matches!(lower.as_str(), "1" | "true" | "yes" | "on" | "y" | "t") {
313                        1
314                    } else {
315                        0
316                    },
317                )
318            }
319            Value::Null => Value::Null,
320            _ => Value::Null,
321        }
322    }
323
324    fn to_string_value(value: Value) -> Value {
325        match value {
326            Value::String(_) => value,
327            Value::I64(v) => Value::String(v.to_string()),
328            Value::I32(v) => Value::String(v.to_string()),
329            Value::I8(v) => Value::String(v.to_string()),
330            Value::I16(v) => Value::String(v.to_string()),
331            Value::U32(v) => Value::String(v.to_string()),
332            Value::U64(v) => Value::String(v.to_string()),
333            Value::U8(v) => Value::String(v.to_string()),
334            Value::U16(v) => Value::String(v.to_string()),
335            Value::F32(v) => Value::String(v.to_string()),
336            Value::F64(v) => Value::String(v.to_string()),
337            Value::Bool(b) => Value::String(b.to_string()),
338            Value::Null => Value::Null,
339            other => Value::String(format!("{:?}", other)),
340        }
341    }
342
343    fn to_json(value: Value) -> Value {
344        match value {
345            Value::String(s) => {
346                // 校验是否为合法 JSON;合法则包装为 Value::Json,否则保留为 String
347                if serde_json::from_str::<serde_json::Value>(&s).is_ok() {
348                    Value::Json(s)
349                } else {
350                    Value::String(s)
351                }
352            }
353            Value::Json(s) => Value::Json(s),
354            other => Value::Json(value_to_json_string(&other)),
355        }
356    }
357
358    fn to_json_storage(value: Value) -> Value {
359        match value {
360            Value::Json(s) => Value::Json(s),
361            Value::String(s) => Value::Json(s),
362            other => Value::Json(value_to_json_string(&other)),
363        }
364    }
365
366    fn to_datetime(value: Value) -> Value {
367        match value {
368            Value::DateTime(s) => Value::DateTime(s),
369            Value::String(s) => Value::DateTime(s),
370            Value::Null => Value::Null,
371            other => Value::DateTime(format!("{:?}", other)),
372        }
373    }
374
375    fn to_datetime_storage(value: Value) -> Value {
376        match value {
377            Value::DateTime(s) => Value::DateTime(s),
378            Value::String(s) => Value::DateTime(s),
379            Value::Null => Value::Null,
380            other => Value::DateTime(format!("{:?}", other)),
381        }
382    }
383
384    fn to_date(value: Value) -> Value {
385        match value {
386            Value::Date(s) => Value::Date(s),
387            Value::String(s) => Value::Date(s),
388            Value::Null => Value::Null,
389            other => Value::Date(format!("{:?}", other)),
390        }
391    }
392
393    fn to_date_storage(value: Value) -> Value {
394        match value {
395            Value::Date(s) => Value::Date(s),
396            Value::String(s) => Value::Date(s),
397            Value::Null => Value::Null,
398            other => Value::Date(format!("{:?}", other)),
399        }
400    }
401
402    fn to_time(value: Value) -> Value {
403        match value {
404            Value::Time(s) => Value::Time(s),
405            Value::String(s) => Value::Time(s),
406            Value::Null => Value::Null,
407            other => Value::Time(format!("{:?}", other)),
408        }
409    }
410
411    fn to_time_storage(value: Value) -> Value {
412        match value {
413            Value::Time(s) => Value::Time(s),
414            Value::String(s) => Value::Time(s),
415            Value::Null => Value::Null,
416            other => Value::Time(format!("{:?}", other)),
417        }
418    }
419
420    fn to_bytes(value: Value) -> Value {
421        match value {
422            Value::Bytes(_) => value,
423            Value::String(s) => Value::Bytes(s.into_bytes()),
424            Value::Null => Value::Null,
425            _ => Value::Null,
426        }
427    }
428
429    fn to_array(value: Value) -> Value {
430        match value {
431            Value::Array(_) => value,
432            Value::Json(s) => {
433                // 尝试解析 JSON 数组;解析失败则包装为单元素数组
434                match serde_json::from_str::<Vec<serde_json::Value>>(&s) {
435                    Ok(json_arr) => {
436                        let items: Vec<Value> = json_arr
437                            .into_iter()
438                            .map(|jv| json_to_value(jv))
439                            .collect();
440                        Value::Array(items)
441                    }
442                    Err(_) => Value::Array(vec![Value::Json(s)]),
443                }
444            }
445            Value::String(s) => {
446                // 尝试解析字符串为 JSON 数组;失败则包装为单元素数组
447                match serde_json::from_str::<Vec<serde_json::Value>>(&s) {
448                    Ok(json_arr) => {
449                        let items: Vec<Value> = json_arr
450                            .into_iter()
451                            .map(|jv| json_to_value(jv))
452                            .collect();
453                        Value::Array(items)
454                    }
455                    Err(_) => Value::Array(vec![Value::String(s)]),
456                }
457            }
458            Value::Null => Value::Null,
459            other => Value::Array(vec![other]),
460        }
461    }
462
463    fn to_array_storage(value: Value) -> Value {
464        match value {
465            Value::Array(items) => {
466                // 序列化为合法 JSON 数组字符串存储
467                let json_arr: Vec<serde_json::Value> =
468                    items.iter().map(|v| value_to_json(&v)).collect();
469                Value::Json(serde_json::to_string(&json_arr).unwrap_or_else(|_| "[]".to_string()))
470            }
471            other => Value::Json(value_to_json_string(&other)),
472        }
473    }
474}
475
476/// 将 `Value` 转换为 `serde_json::Value`
477///
478/// 用于 `to_array_storage` / `to_json_storage` 等场景,确保产生合法 JSON。
479fn value_to_json(value: &Value) -> serde_json::Value {
480    match value {
481        Value::Null => serde_json::Value::Null,
482        Value::Bool(b) => serde_json::Value::Bool(*b),
483        Value::I8(v) => serde_json::Value::Number((*v).into()),
484        Value::I16(v) => serde_json::Value::Number((*v).into()),
485        Value::I32(v) => serde_json::Value::Number((*v).into()),
486        Value::I64(v) => serde_json::Value::Number((*v).into()),
487        Value::U8(v) => serde_json::Value::Number((*v).into()),
488        Value::U16(v) => serde_json::Value::Number((*v).into()),
489        Value::U32(v) => serde_json::Value::Number((*v).into()),
490        Value::U64(v) => serde_json::Value::Number((*v).into()),
491        Value::F32(v) => {
492            serde_json::Number::from_f64(*v as f64).map(serde_json::Value::Number)
493                .unwrap_or(serde_json::Value::Null)
494        }
495        Value::F64(v) => {
496            serde_json::Number::from_f64(*v).map(serde_json::Value::Number)
497                .unwrap_or(serde_json::Value::Null)
498        }
499        Value::Decimal(s) => {
500            // 高精度十进制数:尝试作为数字,否则作为字符串
501            serde_json::from_str(s).unwrap_or_else(|_| serde_json::Value::String(s.clone()))
502        }
503        Value::String(s) => serde_json::Value::String(s.clone()),
504        Value::Bytes(b) => {
505            // 字节值:以 base64 编码字符串形式表示
506            use std::fmt::Write;
507            let mut s = String::with_capacity(b.len() * 2);
508            for byte in b {
509                write!(&mut s, "{:02x}", byte).unwrap();
510            }
511            serde_json::Value::String(s)
512        }
513        Value::Uuid(s) => serde_json::Value::String(s.clone()),
514        Value::Date(s) => serde_json::Value::String(s.clone()),
515        Value::DateTime(s) => serde_json::Value::String(s.clone()),
516        Value::Time(s) => serde_json::Value::String(s.clone()),
517        Value::Json(s) => {
518            serde_json::from_str(s).unwrap_or(serde_json::Value::String(s.clone()))
519        }
520        Value::Array(items) => {
521            serde_json::Value::Array(items.iter().map(value_to_json).collect())
522        }
523        Value::Object(map) => {
524            let mut obj = serde_json::Map::new();
525            for (k, v) in map {
526                obj.insert(k.clone(), value_to_json(v));
527            }
528            serde_json::Value::Object(obj)
529        }
530    }
531}
532
533/// 将 `Value` 转换为 JSON 字符串
534fn value_to_json_string(value: &Value) -> String {
535    serde_json::to_string(&value_to_json(value)).unwrap_or_else(|_| "null".to_string())
536}
537
538/// 将 `serde_json::Value` 转换为内部 `Value`
539///
540/// 用于 `to_array` 等场景,将解析出的 JSON 数组元素转换为内部 Value。
541fn json_to_value(jv: serde_json::Value) -> Value {
542    match jv {
543        serde_json::Value::Null => Value::Null,
544        serde_json::Value::Bool(b) => Value::Bool(b),
545        serde_json::Value::Number(n) => {
546            if let Some(i) = n.as_i64() {
547                Value::I64(i)
548            } else if let Some(u) = n.as_u64() {
549                Value::U64(u)
550            } else if let Some(f) = n.as_f64() {
551                Value::F64(f)
552            } else {
553                Value::Null
554            }
555        }
556        serde_json::Value::String(s) => Value::String(s),
557        serde_json::Value::Array(arr) => {
558            Value::Array(arr.into_iter().map(json_to_value).collect())
559        }
560        serde_json::Value::Object(obj) => {
561            let mut map = std::collections::HashMap::new();
562            for (k, v) in obj {
563                map.insert(k, json_to_value(v));
564            }
565            Value::Object(map)
566        }
567    }
568}
569
570// ============================================================================
571// AccessorRegistry — 注册中心
572// ============================================================================
573
574/// Accessor / Mutator / Cast 注册中心
575///
576/// 管理字段级别的读取器、设置器、类型转换器。
577pub struct AccessorRegistry {
578    /// 字段读取器
579    accessors: HashMap<String, Box<dyn Accessor>>,
580    /// 字段设置器
581    mutators: HashMap<String, Box<dyn Mutator>>,
582    /// 字段类型转换
583    casts: HashMap<String, CastType>,
584}
585
586impl Default for AccessorRegistry {
587    fn default() -> Self {
588        Self::new()
589    }
590}
591
592impl AccessorRegistry {
593    /// 创建空注册中心
594    pub fn new() -> Self {
595        Self {
596            accessors: HashMap::new(),
597            mutators: HashMap::new(),
598            casts: HashMap::new(),
599        }
600    }
601
602    /// 注册 Accessor
603    pub fn register_accessor(&mut self, accessor: Box<dyn Accessor>) {
604        let field = accessor.field().to_string();
605        self.accessors.insert(field, accessor);
606    }
607
608    /// 注册 Mutator
609    pub fn register_mutator(&mut self, mutator: Box<dyn Mutator>) {
610        let field = mutator.field().to_string();
611        self.mutators.insert(field, mutator);
612    }
613
614    /// 注册类型转换
615    pub fn register_cast(&mut self, field: impl Into<String>, cast: CastType) {
616        self.casts.insert(field.into(), cast);
617    }
618
619    /// 应用读取流程:cast_read → accessor.read
620    pub fn read(&self, field: &str, value: Value) -> Value {
621        let v1 = if let Some(cast) = self.casts.get(field) {
622            AttributeCaster::cast_read(value, *cast)
623        } else {
624            value
625        };
626        if let Some(accessor) = self.accessors.get(field) {
627            accessor.read(v1)
628        } else {
629            v1
630        }
631    }
632
633    /// 应用写入流程:mutator.write → cast_write
634    pub fn write(&self, field: &str, value: Value) -> Value {
635        let v1 = if let Some(mutator) = self.mutators.get(field) {
636            mutator.write(value)
637        } else {
638            value
639        };
640        if let Some(cast) = self.casts.get(field) {
641            AttributeCaster::cast_write(v1, *cast)
642        } else {
643            v1
644        }
645    }
646
647    /// 仅应用类型转换(读取方向)
648    pub fn cast_read(&self, field: &str, value: Value) -> Value {
649        if let Some(cast) = self.casts.get(field) {
650            AttributeCaster::cast_read(value, *cast)
651        } else {
652            value
653        }
654    }
655
656    /// 仅应用类型转换(写入方向)
657    pub fn cast_write(&self, field: &str, value: Value) -> Value {
658        if let Some(cast) = self.casts.get(field) {
659            AttributeCaster::cast_write(value, *cast)
660        } else {
661            value
662        }
663    }
664
665    /// 检查字段是否已注册 Accessor
666    pub fn has_accessor(&self, field: &str) -> bool {
667        self.accessors.contains_key(field)
668    }
669
670    /// 检查字段是否已注册 Mutator
671    pub fn has_mutator(&self, field: &str) -> bool {
672        self.mutators.contains_key(field)
673    }
674
675    /// 检查字段是否已注册 Cast
676    pub fn has_cast(&self, field: &str) -> bool {
677        self.casts.contains_key(field)
678    }
679
680    /// 获取字段已注册的 CastType
681    pub fn get_cast(&self, field: &str) -> Option<CastType> {
682        self.casts.get(field).copied()
683    }
684
685    /// 已注册 Accessor 数量
686    pub fn accessor_count(&self) -> usize {
687        self.accessors.len()
688    }
689
690    /// 已注册 Mutator 数量
691    pub fn mutator_count(&self) -> usize {
692        self.mutators.len()
693    }
694
695    /// 已注册 Cast 数量
696    pub fn cast_count(&self) -> usize {
697        self.casts.len()
698    }
699}
700
701// ============================================================================
702// 单元测试
703// ============================================================================
704
705#[cfg(test)]
706mod tests {
707    use super::*;
708
709    // ===== CastType 测试 =====
710
711    #[test]
712    fn test_cast_type_name() {
713        assert_eq!(CastType::Integer.name(), "integer");
714        assert_eq!(CastType::Boolean.name(), "boolean");
715        assert_eq!(CastType::Json.name(), "json");
716        assert_eq!(CastType::DateTime.name(), "datetime");
717    }
718
719    // ===== AttributeCaster - Integer =====
720
721    #[test]
722    fn test_cast_to_integer_from_string() {
723        let v = AttributeCaster::cast_read(Value::String("42".to_string()), CastType::Integer);
724        assert_eq!(v, Value::I64(42));
725    }
726
727    #[test]
728    fn test_cast_to_integer_from_invalid_string() {
729        let v = AttributeCaster::cast_read(Value::String("abc".to_string()), CastType::Integer);
730        assert_eq!(v, Value::Null);
731    }
732
733    #[test]
734    fn test_cast_to_integer_from_bool() {
735        let v = AttributeCaster::cast_read(Value::Bool(true), CastType::Integer);
736        assert_eq!(v, Value::I64(1));
737    }
738
739    #[test]
740    fn test_cast_to_integer_from_float() {
741        let v = AttributeCaster::cast_read(Value::F64(3.7), CastType::Integer);
742        assert_eq!(v, Value::I64(3));
743    }
744
745    #[test]
746    fn test_cast_to_integer_preserves_i64() {
747        let v = AttributeCaster::cast_read(Value::I64(100), CastType::Integer);
748        assert_eq!(v, Value::I64(100));
749    }
750
751    // ===== AttributeCaster - Float =====
752
753    #[test]
754    fn test_cast_to_float_from_string() {
755        let v = AttributeCaster::cast_read(Value::String("3.15".to_string()), CastType::Float);
756        assert_eq!(v, Value::F64(3.15));
757    }
758
759    #[test]
760    fn test_cast_to_float_from_i64() {
761        let v = AttributeCaster::cast_read(Value::I64(42), CastType::Float);
762        assert_eq!(v, Value::F64(42.0));
763    }
764
765    // ===== AttributeCaster - Boolean =====
766
767    #[test]
768    fn test_cast_to_boolean_from_i64_one() {
769        let v = AttributeCaster::cast_read(Value::I64(1), CastType::Boolean);
770        assert_eq!(v, Value::Bool(true));
771    }
772
773    #[test]
774    fn test_cast_to_boolean_from_i64_zero() {
775        let v = AttributeCaster::cast_read(Value::I64(0), CastType::Boolean);
776        assert_eq!(v, Value::Bool(false));
777    }
778
779    #[test]
780    fn test_cast_to_boolean_from_string_true() {
781        let v = AttributeCaster::cast_read(Value::String("true".to_string()), CastType::Boolean);
782        assert_eq!(v, Value::Bool(true));
783    }
784
785    #[test]
786    fn test_cast_to_boolean_from_string_yes() {
787        let v = AttributeCaster::cast_read(Value::String("yes".to_string()), CastType::Boolean);
788        assert_eq!(v, Value::Bool(true));
789    }
790
791    #[test]
792    fn test_cast_to_boolean_from_string_on() {
793        let v = AttributeCaster::cast_read(Value::String("on".to_string()), CastType::Boolean);
794        assert_eq!(v, Value::Bool(true));
795    }
796
797    #[test]
798    fn test_cast_to_boolean_from_string_random() {
799        let v = AttributeCaster::cast_read(Value::String("random".to_string()), CastType::Boolean);
800        assert_eq!(v, Value::Bool(false));
801    }
802
803    #[test]
804    fn test_cast_to_boolean_preserves_bool() {
805        let v = AttributeCaster::cast_read(Value::Bool(true), CastType::Boolean);
806        assert_eq!(v, Value::Bool(true));
807    }
808
809    // ===== AttributeCaster - Boolean Storage(写入方向)=====
810
811    #[test]
812    fn test_cast_to_boolean_storage_from_bool() {
813        let v = AttributeCaster::cast_write(Value::Bool(true), CastType::Boolean);
814        assert_eq!(v, Value::I64(1));
815    }
816
817    #[test]
818    fn test_cast_to_boolean_storage_from_string() {
819        let v = AttributeCaster::cast_write(Value::String("yes".to_string()), CastType::Boolean);
820        assert_eq!(v, Value::I64(1));
821    }
822
823    // ===== AttributeCaster - String =====
824
825    #[test]
826    fn test_cast_to_string_from_i64() {
827        let v = AttributeCaster::cast_read(Value::I64(42), CastType::String);
828        assert_eq!(v, Value::String("42".to_string()));
829    }
830
831    #[test]
832    fn test_cast_to_string_from_bool() {
833        let v = AttributeCaster::cast_read(Value::Bool(true), CastType::String);
834        assert_eq!(v, Value::String("true".to_string()));
835    }
836
837    #[test]
838    fn test_cast_to_string_preserves_string() {
839        let v = AttributeCaster::cast_read(Value::String("hello".to_string()), CastType::String);
840        assert_eq!(v, Value::String("hello".to_string()));
841    }
842
843    // ===== AttributeCaster - Json =====
844
845    #[test]
846    fn test_cast_to_json_from_string() {
847        let v = AttributeCaster::cast_read(
848            Value::String(r#"{"key":"value"}"#.to_string()),
849            CastType::Json,
850        );
851        // 合法 JSON 字符串应转换为 Value::Json
852        assert!(matches!(v, Value::Json(_)));
853        if let Value::Json(s) = v {
854            // 验证 JSON 内容正确
855            let parsed: serde_json::Value = serde_json::from_str(&s).unwrap();
856            assert_eq!(parsed["key"], "value");
857        }
858    }
859
860    #[test]
861    fn test_cast_to_json_from_invalid_string() {
862        let v = AttributeCaster::cast_read(
863            Value::String("not a json".to_string()),
864            CastType::Json,
865        );
866        // 非法 JSON 字符串应保留为 String
867        assert!(matches!(v, Value::String(_)));
868    }
869
870    #[test]
871    fn test_cast_to_json_from_other() {
872        let v = AttributeCaster::cast_read(Value::I64(42), CastType::Json);
873        assert!(matches!(v, Value::Json(_)));
874        if let Value::Json(s) = v {
875            // 验证产生的 JSON 是合法的
876            let parsed: serde_json::Value = serde_json::from_str(&s).unwrap();
877            assert_eq!(parsed, serde_json::Value::Number(42.into()));
878        }
879    }
880
881    // ===== AttributeCaster - DateTime / Date / Time =====
882
883    #[test]
884    fn test_cast_to_datetime_from_string() {
885        let v = AttributeCaster::cast_read(
886            Value::String("2026-07-19T10:00:00Z".to_string()),
887            CastType::DateTime,
888        );
889        assert_eq!(v, Value::DateTime("2026-07-19T10:00:00Z".to_string()));
890    }
891
892    #[test]
893    fn test_cast_to_date_from_string() {
894        let v = AttributeCaster::cast_read(Value::String("2026-07-19".to_string()), CastType::Date);
895        assert_eq!(v, Value::Date("2026-07-19".to_string()));
896    }
897
898    #[test]
899    fn test_cast_to_time_from_string() {
900        let v = AttributeCaster::cast_read(Value::String("10:30:00".to_string()), CastType::Time);
901        assert_eq!(v, Value::Time("10:30:00".to_string()));
902    }
903
904    // ===== AttributeCaster - Bytes =====
905
906    #[test]
907    fn test_cast_to_bytes_from_string() {
908        let v = AttributeCaster::cast_read(Value::String("hello".to_string()), CastType::Bytes);
909        assert_eq!(v, Value::Bytes(b"hello".to_vec()));
910    }
911
912    #[test]
913    fn test_cast_to_bytes_preserves_bytes() {
914        let v = AttributeCaster::cast_read(Value::Bytes(b"data".to_vec()), CastType::Bytes);
915        assert_eq!(v, Value::Bytes(b"data".to_vec()));
916    }
917
918    // ===== AttributeCaster - Array =====
919
920    #[test]
921    fn test_cast_to_array_from_string() {
922        let v = AttributeCaster::cast_read(Value::String("item".to_string()), CastType::Array);
923        assert!(matches!(v, Value::Array(_)));
924        if let Value::Array(arr) = v {
925            assert_eq!(arr.len(), 1);
926        }
927    }
928
929    #[test]
930    fn test_cast_to_array_from_json_string() {
931        // 合法 JSON 数组字符串应被正确解析
932        let v = AttributeCaster::cast_read(
933            Value::String("[1, 2, 3]".to_string()),
934            CastType::Array,
935        );
936        assert!(matches!(v, Value::Array(_)));
937        if let Value::Array(arr) = v {
938            assert_eq!(arr.len(), 3);
939            assert_eq!(arr[0], Value::I64(1));
940            assert_eq!(arr[1], Value::I64(2));
941            assert_eq!(arr[2], Value::I64(3));
942        }
943    }
944
945    #[test]
946    fn test_cast_to_array_from_json_value() {
947        // Value::Json 中的合法 JSON 数组应被正确解析
948        let v = AttributeCaster::cast_read(
949            Value::Json(r#"["a", "b"]"#.to_string()),
950            CastType::Array,
951        );
952        assert!(matches!(v, Value::Array(_)));
953        if let Value::Array(arr) = v {
954            assert_eq!(arr.len(), 2);
955            assert_eq!(arr[0], Value::String("a".to_string()));
956            assert_eq!(arr[1], Value::String("b".to_string()));
957        }
958    }
959
960    #[test]
961    fn test_cast_to_array_preserves_array() {
962        let arr = vec![Value::I64(1), Value::I64(2)];
963        let v = AttributeCaster::cast_read(Value::Array(arr.clone()), CastType::Array);
964        assert_eq!(v, Value::Array(arr));
965    }
966
967    #[test]
968    fn test_cast_to_array_storage_serializes_to_json() {
969        let v = AttributeCaster::cast_write(
970            Value::Array(vec![Value::I64(1), Value::I64(2)]),
971            CastType::Array,
972        );
973        assert!(matches!(v, Value::Json(_)));
974        if let Value::Json(s) = v {
975            // 验证产生的 JSON 是合法的 JSON 数组
976            let parsed: serde_json::Value = serde_json::from_str(&s).unwrap();
977            assert!(parsed.is_array());
978            assert_eq!(parsed[0], serde_json::Value::Number(1.into()));
979            assert_eq!(parsed[1], serde_json::Value::Number(2.into()));
980        }
981    }
982
983    #[test]
984    fn test_cast_to_array_storage_not_debug_format() {
985        // P2-5 回归测试:确保不再使用 Debug 格式([I64(1), I64(2)])
986        let v = AttributeCaster::cast_write(
987            Value::Array(vec![Value::I64(1), Value::I64(2)]),
988            CastType::Array,
989        );
990        if let Value::Json(s) = v {
991            // Debug 格式会包含 "I64" 字样,合法 JSON 不会
992            assert!(!s.contains("I64"), "JSON 不应包含 Debug 格式 I64: {}", s);
993            // 应为合法 JSON 数组
994            let parsed: serde_json::Value = serde_json::from_str(&s).unwrap();
995            assert!(parsed.is_array());
996        }
997    }
998
999    #[test]
1000    fn test_cast_to_json_storage_from_other() {
1001        let v = AttributeCaster::cast_write(Value::I64(42), CastType::Json);
1002        assert!(matches!(v, Value::Json(_)));
1003        if let Value::Json(s) = v {
1004            // 验证产生的 JSON 是合法的
1005            let parsed: serde_json::Value = serde_json::from_str(&s).unwrap();
1006            assert_eq!(parsed, serde_json::Value::Number(42.into()));
1007        }
1008    }
1009
1010    // ===== ClosureAccessor / ClosureMutator =====
1011
1012    #[test]
1013    fn test_closure_accessor() {
1014        let accessor = ClosureAccessor::new("name", |v| match v {
1015            Value::String(s) => Value::String(s.to_uppercase()),
1016            other => other,
1017        });
1018        let v = accessor.read(Value::String("alice".to_string()));
1019        assert_eq!(v, Value::String("ALICE".to_string()));
1020        assert_eq!(accessor.field(), "name");
1021    }
1022
1023    #[test]
1024    fn test_closure_mutator() {
1025        let mutator = ClosureMutator::new("email", |v| match v {
1026            Value::String(s) => Value::String(s.to_lowercase()),
1027            other => other,
1028        });
1029        let v = mutator.write(Value::String("ALICE@EXAMPLE.COM".to_string()));
1030        assert_eq!(v, Value::String("alice@example.com".to_string()));
1031        assert_eq!(mutator.field(), "email");
1032    }
1033
1034    // ===== AccessorRegistry - 基本操作 =====
1035
1036    #[test]
1037    fn test_registry_empty() {
1038        let r = AccessorRegistry::new();
1039        assert_eq!(r.accessor_count(), 0);
1040        assert_eq!(r.mutator_count(), 0);
1041        assert_eq!(r.cast_count(), 0);
1042    }
1043
1044    #[test]
1045    fn test_registry_register_cast() {
1046        let mut r = AccessorRegistry::new();
1047        r.register_cast("is_admin", CastType::Boolean);
1048        assert!(r.has_cast("is_admin"));
1049        assert_eq!(r.get_cast("is_admin"), Some(CastType::Boolean));
1050        assert_eq!(r.cast_count(), 1);
1051    }
1052
1053    #[test]
1054    fn test_registry_register_accessor() {
1055        let mut r = AccessorRegistry::new();
1056        r.register_accessor(Box::new(ClosureAccessor::new("name", |v| match v {
1057            Value::String(s) => Value::String(s.to_uppercase()),
1058            other => other,
1059        })));
1060        assert!(r.has_accessor("name"));
1061        assert_eq!(r.accessor_count(), 1);
1062    }
1063
1064    #[test]
1065    fn test_registry_register_mutator() {
1066        let mut r = AccessorRegistry::new();
1067        r.register_mutator(Box::new(ClosureMutator::new("email", |v| match v {
1068            Value::String(s) => Value::String(s.to_lowercase()),
1069            other => other,
1070        })));
1071        assert!(r.has_mutator("email"));
1072        assert_eq!(r.mutator_count(), 1);
1073    }
1074
1075    // ===== AccessorRegistry - read/write 流程 =====
1076
1077    #[test]
1078    fn test_registry_read_applies_cast_then_accessor() {
1079        let mut r = AccessorRegistry::new();
1080        r.register_cast("is_admin", CastType::Boolean);
1081        r.register_accessor(Box::new(ClosureAccessor::new("is_admin", |v| {
1082            if v == Value::Bool(true) {
1083                Value::String("管理员".to_string())
1084            } else {
1085                Value::String("普通用户".to_string())
1086            }
1087        })));
1088
1089        // 读取:I64(1) → cast(Boolean) → Bool(true) → accessor → String("管理员")
1090        let v = r.read("is_admin", Value::I64(1));
1091        assert_eq!(v, Value::String("管理员".to_string()));
1092    }
1093
1094    #[test]
1095    fn test_registry_write_applies_mutator_then_cast() {
1096        let mut r = AccessorRegistry::new();
1097        r.register_cast("is_admin", CastType::Boolean);
1098        r.register_mutator(Box::new(ClosureMutator::new("is_admin", |v| match v {
1099            Value::String(s) => {
1100                let lower = s.to_lowercase();
1101                Value::Bool(lower == "admin" || lower == "true")
1102            }
1103            other => other,
1104        })));
1105
1106        // 写入:String("admin") → mutator → Bool(true) → cast → I64(1)
1107        let v = r.write("is_admin", Value::String("admin".to_string()));
1108        assert_eq!(v, Value::I64(1));
1109    }
1110
1111    #[test]
1112    fn test_registry_read_without_cast_or_accessor() {
1113        let r = AccessorRegistry::new();
1114        let v = r.read("any_field", Value::I64(42));
1115        assert_eq!(v, Value::I64(42));
1116    }
1117
1118    #[test]
1119    fn test_registry_write_without_cast_or_mutator() {
1120        let r = AccessorRegistry::new();
1121        let v = r.write("any_field", Value::I64(42));
1122        assert_eq!(v, Value::I64(42));
1123    }
1124
1125    #[test]
1126    fn test_registry_cast_read_only() {
1127        let mut r = AccessorRegistry::new();
1128        r.register_cast("is_admin", CastType::Boolean);
1129
1130        let v = r.cast_read("is_admin", Value::I64(1));
1131        assert_eq!(v, Value::Bool(true));
1132    }
1133
1134    #[test]
1135    fn test_registry_cast_write_only() {
1136        let mut r = AccessorRegistry::new();
1137        r.register_cast("is_admin", CastType::Boolean);
1138
1139        let v = r.cast_write("is_admin", Value::Bool(true));
1140        assert_eq!(v, Value::I64(1));
1141    }
1142
1143    // ===== 综合场景测试 =====
1144
1145    #[test]
1146    fn test_complex_user_model_scenario() {
1147        let mut r = AccessorRegistry::new();
1148
1149        // 1. is_admin: i64(0/1) ↔ bool
1150        r.register_cast("is_admin", CastType::Boolean);
1151
1152        // 2. email: 自动转小写
1153        r.register_mutator(Box::new(ClosureMutator::new("email", |v| match v {
1154            Value::String(s) => Value::String(s.to_lowercase()),
1155            other => other,
1156        })));
1157
1158        // 3. full_name: 拼接 first + last(演示 accessor)
1159        r.register_accessor(Box::new(ClosureAccessor::new(
1160            "full_name",
1161            |v| v, // 简化:直接返回
1162        )));
1163
1164        // 4. settings: JSON 字段
1165        r.register_cast("settings", CastType::Json);
1166
1167        // 5. created_at: DateTime
1168        r.register_cast("created_at", CastType::DateTime);
1169
1170        // 读取 is_admin
1171        let v = r.read("is_admin", Value::I64(1));
1172        assert_eq!(v, Value::Bool(true));
1173
1174        // 写入 email
1175        let v = r.write("email", Value::String("Alice@Example.COM".to_string()));
1176        assert_eq!(v, Value::String("alice@example.com".to_string()));
1177
1178        // 读取 settings(合法 JSON 应转换为 Value::Json)
1179        let v = r.read("settings", Value::String(r#"{"theme":"dark"}"#.to_string()));
1180        assert!(matches!(v, Value::Json(_)));
1181
1182        assert_eq!(r.accessor_count(), 1);
1183        assert_eq!(r.mutator_count(), 1);
1184        assert_eq!(r.cast_count(), 3);
1185    }
1186
1187    // ===== Default 测试 =====
1188
1189    #[test]
1190    fn test_default_is_empty() {
1191        let r = AccessorRegistry::default();
1192        assert_eq!(r.accessor_count(), 0);
1193        assert_eq!(r.mutator_count(), 0);
1194        assert_eq!(r.cast_count(), 0);
1195    }
1196}