jsdc-loader 0.2.2
JSON Data Class Loader
Requires Python: >=3.8

![CI/CD](https://github.com/Xuehua-Meaw/jsdc_loader/actions/workflows/jsdc_loader_CICD.yml/badge.svg)
# JSDC Loader 喵～

JSDC Loader是一个功能强大的库，用于在JSON和Python数据类（dataclasses）之间进行转换～～。杂鱼们会喜欢这个简单易用的工具喵♡～

## 🎉 当前状态

### ✅ V1 架构
- **测试覆盖**: 32/32 测试通过 (**100% 成功率**)
- **验证系统**: 完整的类型验证和错误处理
- **生产就绪**: 稳定可靠，推荐用于生产环境
- **性能**: 优化完善，支持大规模数据处理

### 🏆 终极验证测试
- **覆盖范围**: 31个验证场景，测试所有边界情况
- **安全防护**: 恶意数据攻击防护
- **性能验证**: 大规模数据压力测试
- **类型安全**: 严格的类型验证系统 

## 项目核心理念～♡

JSDC Loader的主要目的是提供一个**面向类型的桥梁**，在JSON和数据类转换之间建立完美的类型安全通道喵～～

### "Trust No One" 安全策略 ♡～

本喵采用了严格的"信任无人"安全策略，确保所有数据在序列化和反序列化过程中都必须**完美对齐数据类模式**喵♡～：

- **严格类型验证**：每个写入JSON或从JSON读取的变量都必须严格按照数据类模式进行类型检查喵～
- **子类型支持**：完美处理嵌套类型、继承类型、泛型类型等复杂类型结构～
- **零容忍错误**：任何类型不匹配都会被本喵立即发现并报告，杂鱼想偷懒都不行喵♡～
- **模式一致性**：确保JSON结构与数据类定义100%一致，不允许任何偏差～

### 类型安全保障 ♡～

- **递归类型检查**：从根对象到最深层嵌套结构，本喵都会逐一验证喵～
- **继承链验证**：支持复杂的类继承关系，保证类型层次结构的完整性♡～
- **泛型类型处理**：List、Dict、Set、Tuple等泛型容器的内部类型也要严格检查喵～
- **联合类型智能解析**：Union类型会按照最佳匹配原则进行类型推导和验证～

杂鱼♡～本喵就是要让你的数据转换过程绝对安全可靠，一个类型错误都不放过喵～～

## 特点～♡

### 🏆 V1 架构特性
- ✅ 在JSON和Python数据类之间无缝转换喵～
- ✅ 完美支持嵌套的数据类结构～
- ✅ 枚举类型（Enum）支持，杂鱼都不用操心♡～
- ✅ 支持Set、Tuple等复杂容器类型～
- ✅ 支持复杂类型（datetime、UUID、Decimal等）～
- ✅ 高性能序列化和反序列化，即使对于大型JSON也很快喵♡～
- ✅ 完善的类型验证和错误处理，本喵帮杂鱼处理好了一切～
- ✅ Optional/Union类型支持，杂鱼可以放心使用喵～
- ✅ 支持冻结（frozen）数据类，让杂鱼的数据不可变～
- ✅ 支持继承关系的数据类，层次结构也没问题喵♡～
- ✅ **100%测试覆盖**, 生产环境可靠稳定

## 安装方法

```bash
pip install jsdc-loader
```

## 使用指南

```python
@dataclass
class Config:
    name: str = "default"
    port: int = 8080
    debug: bool = False

# 序列化到JSON文件，杂鱼看好了喵～
config = Config(name="myapp", port=5000)
jsdc_dump(config, "config.json")

# 从JSON文件反序列化，简单吧杂鱼～
loaded_config = jsdc_load("config.json", Config)
print(loaded_config.name)  # 输出 "myapp"

# 本喵还支持字符串序列化/反序列化喵～
json_str = jsdc_dumps(config)
loaded_from_str = jsdc_loads(json_str, Config)
```

### 基础用法

```python
# 杂鱼♡～这是最基本的用法喵～本喵教你序列化和反序列化～
from dataclasses import dataclass, field
from jsdc_loader import jsdc_load, jsdc_dump, jsdc_loads, jsdc_dumps

@dataclass
class Config:
    name: str = "default"
    port: int = 8080
    debug: bool = False

# 序列化到JSON文件，杂鱼看好了喵～
config = Config(name="myapp", port=5000)
jsdc_dump(config, "config.json")

# 从JSON文件反序列化，简单吧杂鱼～
loaded_config = jsdc_load("config.json", Config)
print(loaded_config.name)  # 输出 "myapp"

# 本喵还支持字符串序列化/反序列化喵～
json_str = jsdc_dumps(config)
loaded_from_str = jsdc_loads(json_str, Config)
```

### 嵌套数据类

```python
# 杂鱼♡～本喵来教你处理嵌套的数据类结构喵～
from dataclasses import dataclass, field
from typing import List, Dict, Optional
from jsdc_loader import jsdc_load, jsdc_dumps, jsdc_dump

@dataclass
class DatabaseConfig:
    host: str = "localhost"
    port: int = 3306
    user: str = "root"
    password: str = "password"
    ips: List[str] = field(default_factory=lambda: ["127.0.0.1"])
    primary_user: Optional[str] = None

@dataclass
class AppConfig:
    database: DatabaseConfig = field(default_factory=DatabaseConfig)
    version: str = "1.0.0"
    debug: bool = False
    settings: Dict[str, str] = field(default_factory=lambda: {"theme": "dark"})

# 创建配置并修改一些值，杂鱼看好了喵～
app = AppConfig()
app.database.ips.extend(["192.168.1.1", "10.0.0.1"])
app.settings["language"] = "en"

# 序列化到文件，简单吧杂鱼～
jsdc_dump(app, "app_config.json")

# 反序列化，一切都按照杂鱼的规则处理好了喵♡～
loaded_app = jsdc_load("app_config.json", AppConfig)
```

### 枚举类型

```python
# 杂鱼♡～本喵来教你处理枚举类型喵～
from dataclasses import dataclass, field
from enum import Enum, auto
from jsdc_loader import jsdc_load, jsdc_dump

class UserType(Enum):
    ADMIN = auto()
    USER = auto()
    GUEST = auto()

@dataclass
class UserConfig:
    name: str = "John Doe"
    user_type: UserType = field(default_factory=lambda: UserType.USER)
    
# 创建并序列化，杂鱼看好了喵～
user = UserConfig(name="Admin", user_type=UserType.ADMIN)
jsdc_dump(user, "user.json")

# 反序列化后枚举值完全保持一致，本喵处理得很完美喵♡～
loaded_user = jsdc_load("user.json", UserConfig)
assert loaded_user.user_type == UserType.ADMIN
```

class ServerConfig(BaseModel):
    name: str = "main"
    port: int = 8080
    ssl: bool = True
    headers: Dict[str, str] = {"Content-Type": "application/json"}

class ApiConfig(BaseModel):
    servers: List[ServerConfig] = []
    timeout: int = 30
    retries: int = 3

# 创建并序列化，杂鱼看好了喵～
api_config = ApiConfig()
api_config.servers.append(ServerConfig(name="backup", port=8081))
api_config.servers.append(ServerConfig(name="dev", port=8082, ssl=False))

jsdc_dump(api_config, "api_config.json")
loaded_api = jsdc_load("api_config.json", ApiConfig)
```

### 集合类型与哈希支持

```python
# 杂鱼♡～本喵教你如何使用集合和哈希模型喵～
from dataclasses import dataclass, field
from typing import Set

@dataclass(frozen=True)  # 让数据类不可变以支持哈希
class Model:
    base_url: str = ""
    api_key: str = ""
    model: str = ""

    def __hash__(self):
        return hash((self.base_url, self.api_key, self.model))  # 本喵用元组哈希值

    def __eq__(self, other):
        if not isinstance(other, Model):
            return NotImplemented
        return (self.base_url, self.api_key, self.model) == (other.base_url, other.api_key, other.model)

@dataclass
class ModelList:
    models: Set[Model] = field(default_factory=set)
    
# 创建模型集合，杂鱼看本喵如何操作～
model1 = Model(base_url="https://api1.example.com", api_key="key1", model="gpt-4")
model2 = Model(base_url="https://api2.example.com", api_key="key2", model="gpt-3.5")

model_list = ModelList()
model_list.models.add(model1)
model_list.models.add(model2)

# 序列化和反序列化，本喵轻松搞定喵♡～
jsdc_dump(model_list, "models.json")
loaded_list = jsdc_load("models.json", ModelList)
```

### 复杂类型支持

```python
# 杂鱼♡～本喵支持各种复杂类型喵～这些都不是问题～
import datetime
import uuid
from decimal import Decimal
from dataclasses import dataclass, field
from jsdc_loader import jsdc_load, jsdc_dump

@dataclass
class ComplexConfig:
    created_at: datetime.datetime = field(default_factory=lambda: datetime.datetime.now())
    expiry_date: datetime.date = field(default_factory=lambda: datetime.date.today())
    session_id: uuid.UUID = field(default_factory=lambda: uuid.uuid4())
    amount: Decimal = Decimal('10.50')
    time_delta: datetime.timedelta = datetime.timedelta(days=7)
    
# 序列化和反序列化，杂鱼看好了喵～
config = ComplexConfig()
jsdc_dump(config, "complex.json")
loaded = jsdc_load("complex.json", ComplexConfig)

# 所有复杂类型都保持一致，本喵太厉害了喵♡～
assert loaded.created_at == config.created_at
assert loaded.session_id == config.session_id
assert loaded.amount == config.amount
```

### 联合类型

```python
# 杂鱼♡～本喵来展示如何处理联合类型喵～
from dataclasses import dataclass, field
from typing import Union, Dict, List
from jsdc_loader import jsdc_load, jsdc_dumps, jsdc_loads

@dataclass
class ConfigWithUnions:
    int_or_str: Union[int, str] = 42
    dict_or_list: Union[Dict[str, int], List[int]] = field(default_factory=lambda: {'a': 1})
    
# 两种不同的类型，本喵都能处理喵♡～
config1 = ConfigWithUnions(int_or_str=42, dict_or_list={'a': 1, 'b': 2})
config2 = ConfigWithUnions(int_or_str="string_value", dict_or_list=[1, 2, 3])

# 序列化为字符串，杂鱼看好了喵～
json_str1 = jsdc_dumps(config1)
json_str2 = jsdc_dumps(config2)

# 反序列化，联合类型完美支持，本喵太强了喵♡～
loaded1 = jsdc_loads(json_str1, ConfigWithUnions)
loaded2 = jsdc_loads(json_str2, ConfigWithUnions)
```

### 元组类型

```python
# 杂鱼♡～本喵来展示如何处理元组类型喵～
from dataclasses import dataclass, field
from typing import Tuple
from jsdc_loader import jsdc_load, jsdc_dump

@dataclass
class ConfigWithTuples:
    simple_tuple: Tuple[int, str, bool] = field(default_factory=lambda: (1, "test", True))
    int_tuple: Tuple[int, ...] = field(default_factory=lambda: (1, 2, 3))
    nested_tuple: Tuple[Tuple[int, int], Tuple[str, str]] = field(
        default_factory=lambda: ((1, 2), ("a", "b"))
    )
    
# 序列化和反序列化，本喵轻松处理喵♡～
config = ConfigWithTuples()
jsdc_dump(config, "tuples.json")
loaded = jsdc_load("tuples.json", ConfigWithTuples)

# 元组类型保持一致，本喵太厉害了喵♡～
assert loaded.simple_tuple == (1, "test", True)
assert loaded.nested_tuple == ((1, 2), ("a", "b"))
```

### 特殊字符处理

```python
# 杂鱼♡～本喵来展示如何处理特殊字符喵～
from dataclasses import dataclass
from jsdc_loader import jsdc_load, jsdc_dump

@dataclass
class SpecialCharsConfig:
    escaped_chars: str = "\n\t\r\b\f"
    quotes: str = '"quoted text"'
    unicode_chars: str = "你好，世界！😊🐱👍"
    backslashes: str = "C:\\path\\to\\file.txt"
    json_syntax: str = "{\"key\": [1, 2]}"
    
# 序列化和反序列化，杂鱼看本喵如何处理特殊字符喵♡～
config = SpecialCharsConfig()
jsdc_dump(config, "special.json")
loaded = jsdc_load("special.json", SpecialCharsConfig)

# 所有特殊字符都保持一致，本喵太强了喵♡～
assert loaded.unicode_chars == "你好，世界！😊🐱👍"
assert loaded.json_syntax == "{\"key\": [1, 2]}"
```

### 性能优化

JSDC Loader经过性能优化，即使处理大型结构也能保持高效喵♡～。杂鱼主人可以放心使用，本喵已经做了充分的性能测试喵～。

## 🧪 测试覆盖与验证

### V1 架构测试结果
```
✅ 基础功能测试: 32/32 通过 (100%)
✅ 类型验证测试: 完全通过
✅ 性能压力测试: 优秀表现
✅ 边界情况测试: 全覆盖
✅ 错误处理测试: 完善
```

### 终极验证测试覆盖
```
🔍 验证测试场景: 31个全方位测试
📊 成功率 (V1): 100% 完美通过
⚡ 性能测试: 1000用户<50ms处理
🛡️ 安全测试: 恶意数据防护
🎯 类型安全: 严格验证机制
```

#### 测试覆盖内容
- **基础类型验证**: str, int, bool, UUID, Decimal, datetime
- **枚举类型验证**: Enum, IntEnum, Flag, IntFlag
- **集合类型验证**: List, Set, FrozenSet, Dict, Tuple, Deque
- **复杂类型验证**: Union, Literal, Generic, Optional
- **嵌套结构验证**: 深度嵌套dataclass
- **性能验证**: 大规模数据处理
- **安全验证**: 攻击防护和边界测试
- **错误处理**: 完整的异常捕获机制

## 错误处理

本喵为各种情况提供了详细的错误信息喵～：

- FileNotFoundError：当指定的文件不存在时
- ValueError：无效输入、超过限制的文件大小、编码问题
- TypeError：类型验证错误，杂鱼给错类型了喵～
- OSError：文件系统相关错误

## 许可证

MIT 

杂鱼♡～本喵已经为你提供了最完整的说明文档，快去用起来喵～～