新增 fieldx 包,提供基于预定义 Schema 生成 map[string]any 对象的功能。 主要特性: - 支持固定值字段 (string)、字段引用 (field) 和嵌套对象 (object) - 支持点号分隔的嵌套路径访问 (如 "user.name") - 提供多种 Schema 创建方式 (JSON、Map、编程方式) - 完善的错误处理和文档示例
293 lines
5.6 KiB
Markdown
293 lines
5.6 KiB
Markdown
# FieldX - Schema-based Object Generator
|
|
|
|
FieldX 提供了基于预定义 Schema 生成 `map[string]any` 对象的功能。
|
|
|
|
## 功能特性
|
|
|
|
- **固定值字段 (string)**: 在生成的对象中设置固定的字符串值
|
|
- **字段引用 (field)**: 从源对象中获取指定字段的值,支持嵌套路径访问
|
|
- **嵌套对象 (object)**: 支持生成多层嵌套的复杂对象结构
|
|
|
|
## 快速开始
|
|
|
|
```go
|
|
import "git.fsdpf.net/go/reflux/fieldx"
|
|
|
|
// 1. 定义 JSON Schema
|
|
jsonSchema := `{
|
|
"name": {"type": "field", "value": "userName"},
|
|
"status": {"type": "string", "value": "active"}
|
|
}`
|
|
|
|
// 2. 从 JSON 创建 Schema
|
|
schema, _ := fieldx.SchemaFromJSON(jsonSchema)
|
|
|
|
// 3. 直接生成对象 (一行代码!)
|
|
source := map[string]any{"userName": "Alice"}
|
|
result, _ := schema.Generate(source)
|
|
|
|
// result: map[name:Alice status:active]
|
|
```
|
|
|
|
## 使用示例
|
|
|
|
### 推荐方式: 直接使用 Schema
|
|
|
|
最简单直接的方式:
|
|
|
|
```go
|
|
import "git.fsdpf.net/go/reflux/fieldx"
|
|
|
|
// 1. 从 JSON 创建 Schema
|
|
schema, _ := fieldx.SchemaFromJSON(`{
|
|
"name": {"type": "field", "value": "userName"},
|
|
"status": {"type": "string", "value": "active"}
|
|
}`)
|
|
|
|
// 2. 直接生成对象
|
|
source := map[string]any{"userName": "Alice"}
|
|
result, _ := schema.Generate(source)
|
|
// result: map[name:Alice status:active]
|
|
```
|
|
|
|
### 创建 Schema 的方式
|
|
|
|
#### 方式一: SchemaFromJSON (推荐)
|
|
```go
|
|
schema, _ := fieldx.SchemaFromJSON(jsonStr)
|
|
```
|
|
|
|
#### 方式二: json.Unmarshal
|
|
```go
|
|
var schema fieldx.Schema
|
|
json.Unmarshal([]byte(jsonStr), &schema)
|
|
```
|
|
|
|
#### 方式三: SchemaFromMap
|
|
```go
|
|
var data map[string]any
|
|
json.Unmarshal([]byte(jsonStr), &data)
|
|
schema, _ := fieldx.SchemaFromMap(data)
|
|
```
|
|
|
|
#### 方式四: 编程方式
|
|
```go
|
|
schema := fieldx.Schema{
|
|
"field": fieldx.Field{
|
|
Type: fieldx.FieldTypeString,
|
|
Value: "value",
|
|
},
|
|
}
|
|
```
|
|
|
|
### 嵌套对象示例
|
|
|
|
```go
|
|
schema := fieldx.Schema{
|
|
"type": fieldx.Field{
|
|
Type: fieldx.FieldTypeString,
|
|
Value: "user_profile",
|
|
},
|
|
"user": fieldx.Field{
|
|
Type: fieldx.FieldTypeObject,
|
|
Fields: fieldx.Schema{
|
|
"id": fieldx.Field{
|
|
Type: fieldx.FieldTypeField,
|
|
Value: "userId",
|
|
},
|
|
"name": fieldx.Field{
|
|
Type: fieldx.FieldTypeField,
|
|
Value: "userName",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
source := map[string]any{
|
|
"userId": 123,
|
|
"userName": "Alice",
|
|
}
|
|
|
|
result, _ := schema.Generate(source)
|
|
// result: {"type": "user_profile", "user": {"id": 123, "name": "Alice"}}
|
|
```
|
|
|
|
### 嵌套路径访问
|
|
|
|
支持使用点号分隔的路径从嵌套的源对象中获取值:
|
|
|
|
```go
|
|
schema := fieldx.Schema{
|
|
"userId": fieldx.Field{
|
|
Type: fieldx.FieldTypeField,
|
|
Value: "user.id", // 使用点号访问嵌套字段
|
|
},
|
|
"userEmail": fieldx.Field{
|
|
Type: fieldx.FieldTypeField,
|
|
Value: "user.contact.email", // 支持多层嵌套
|
|
},
|
|
}
|
|
|
|
source := map[string]any{
|
|
"user": map[string]any{
|
|
"id": 456,
|
|
"contact": map[string]any{
|
|
"email": "alice@example.com",
|
|
},
|
|
},
|
|
}
|
|
|
|
result, _ := schema.Generate(source)
|
|
// result: {"userId": 456, "userEmail": "alice@example.com"}
|
|
```
|
|
|
|
## 字段类型说明
|
|
|
|
### FieldTypeString
|
|
固定字符串值类型。
|
|
|
|
```go
|
|
fieldx.Field{
|
|
Type: fieldx.FieldTypeString,
|
|
Value: "固定的字符串值",
|
|
}
|
|
```
|
|
|
|
### FieldTypeField
|
|
从源对象获取字段值,支持点号分隔的嵌套路径。
|
|
|
|
```go
|
|
fieldx.Field{
|
|
Type: fieldx.FieldTypeField,
|
|
Value: "user.profile.name", // 支持嵌套路径
|
|
}
|
|
```
|
|
|
|
### FieldTypeObject
|
|
嵌套对象类型,使用 `Fields` 字段定义子结构。
|
|
|
|
```go
|
|
fieldx.Field{
|
|
Type: fieldx.FieldTypeObject,
|
|
Fields: fieldx.Schema{
|
|
// 嵌套的字段定义
|
|
},
|
|
}
|
|
```
|
|
|
|
## JSON Schema 格式
|
|
|
|
Schema 可以从 JSON 反序列化,这是最方便的使用方式:
|
|
|
|
### 基本格式
|
|
|
|
```json
|
|
{
|
|
"字段名": {
|
|
"type": "string|field|object",
|
|
"value": "根据type不同而不同",
|
|
"fields": {/* 当type为object时使用 */}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 类型说明
|
|
|
|
**1. string** - 固定字符串值
|
|
```json
|
|
{"type": "string", "value": "固定值"}
|
|
```
|
|
|
|
**2. field** - 从源对象获取字段(支持点号分隔的嵌套路径)
|
|
```json
|
|
{"type": "field", "value": "user.name"}
|
|
```
|
|
|
|
**3. object** - 嵌套对象
|
|
```json
|
|
{
|
|
"type": "object",
|
|
"fields": {
|
|
"子字段名": {"type": "...", "value": "..."}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 完整 JSON Schema 示例
|
|
|
|
```json
|
|
{
|
|
"type": {
|
|
"type": "string",
|
|
"value": "user_profile"
|
|
},
|
|
"userId": {
|
|
"type": "field",
|
|
"value": "user.id"
|
|
},
|
|
"userName": {
|
|
"type": "field",
|
|
"value": "user.name"
|
|
},
|
|
"contact": {
|
|
"type": "object",
|
|
"fields": {
|
|
"email": {
|
|
"type": "field",
|
|
"value": "user.email"
|
|
},
|
|
"phone": {
|
|
"type": "string",
|
|
"value": "N/A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
使用此 Schema:
|
|
|
|
```go
|
|
// 1. 从 JSON 创建 Schema
|
|
schema, _ := fieldx.SchemaFromJSON(jsonSchema)
|
|
|
|
// 2. 准备源数据
|
|
source := map[string]any{
|
|
"user": map[string]any{
|
|
"id": 123,
|
|
"name": "Alice",
|
|
"email": "alice@example.com",
|
|
},
|
|
}
|
|
|
|
// 3. 生成对象
|
|
result, _ := schema.Generate(source)
|
|
|
|
// 结果:
|
|
// {
|
|
// "type": "user_profile",
|
|
// "userId": 123,
|
|
// "userName": "Alice",
|
|
// "contact": {
|
|
// "email": "alice@example.com",
|
|
// "phone": "N/A"
|
|
// }
|
|
// }
|
|
```
|
|
|
|
## 错误处理
|
|
|
|
当引用的字段不存在时,`Generate()` 方法会返回错误:
|
|
|
|
```go
|
|
result, err := schema.Generate(source)
|
|
if err != nil {
|
|
// 处理错误,例如:
|
|
// "failed to generate field xxx: field not found: yyy"
|
|
}
|
|
```
|
|
|
|
## 完整示例
|
|
|
|
查看 [example_test.go](example_test.go) 获取更多使用示例。
|