initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
config.json
|
32
core/data-clip-builder.go
Normal file
32
core/data-clip-builder.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type DataClipBuilder struct {
|
||||
path string
|
||||
type_ any
|
||||
}
|
||||
|
||||
func (receiver *DataClipBuilder) InFile(filename string) {
|
||||
wd, _ := os.Getwd()
|
||||
receiver.path = filepath.Join(wd, filename)
|
||||
}
|
||||
|
||||
func (receiver *DataClipBuilder) UnderDir(dirpath string, filename string) {
|
||||
receiver.path = filepath.Join(dirpath, filename)
|
||||
}
|
||||
|
||||
func (receiver *DataClipBuilder) RegisterType(data interface{}) {
|
||||
receiver.type_ = reflect.New(reflect.TypeOf(data)).Interface()
|
||||
}
|
||||
|
||||
func (receiver *DataClipBuilder) Build() DataClip {
|
||||
return DataClip{
|
||||
path: receiver.path,
|
||||
type_: receiver.type_,
|
||||
}
|
||||
}
|
64
core/data-clip.go
Normal file
64
core/data-clip.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type DataClip struct {
|
||||
path string
|
||||
type_ any
|
||||
}
|
||||
|
||||
func (receiver *DataClip) checkFileExists(filepath string) (bool, error) {
|
||||
if _, err := os.Stat(filepath); err == nil {
|
||||
return true, nil
|
||||
} else if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *DataClip) Setup(data interface{}) interface{} {
|
||||
if exists, err := receiver.checkFileExists(receiver.path); err == nil {
|
||||
if exists {
|
||||
// load data
|
||||
return receiver.LoadData()
|
||||
} else {
|
||||
// save default data
|
||||
receiver.SaveData(data)
|
||||
return data
|
||||
}
|
||||
} else {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func (receiver *DataClip) LoadData() interface{} {
|
||||
data, err := os.ReadFile(receiver.path)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to Read Data File: %v", err)
|
||||
}
|
||||
|
||||
// 使用反射获取 defaultConfig 的类型
|
||||
if err := json.Unmarshal(data, receiver.type_); err != nil {
|
||||
log.Fatalf("Failed to Unmarshal Data File: %v", err)
|
||||
}
|
||||
log.Printf("Loaded Data from File: %s", receiver.path)
|
||||
return reflect.ValueOf(receiver.type_).Elem().Interface()
|
||||
}
|
||||
|
||||
func (receiver *DataClip) SaveData(data interface{}) {
|
||||
jsonData, err := json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("Error Encoding Default Data: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(receiver.path, jsonData, 0644); err != nil {
|
||||
log.Fatalf("Failed to Write Default Data to File: %v", err)
|
||||
}
|
||||
log.Printf("Saved Default Data to File: %s", receiver.path)
|
||||
}
|
27
main.go
Normal file
27
main.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"json-dataloader-golang/core"
|
||||
"json-dataloader-golang/utils"
|
||||
)
|
||||
|
||||
type SampleData struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
func (receiver *SampleData) Default() {
|
||||
receiver.Data = "default"
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := SampleData{}
|
||||
|
||||
dataClipBuilder := core.DataClipBuilder{}
|
||||
dataClipBuilder.InFile("config.json")
|
||||
dataClipBuilder.RegisterType(data)
|
||||
|
||||
dataClip := dataClipBuilder.Build()
|
||||
data = dataClip.Setup(data).(SampleData)
|
||||
|
||||
utils.PrintStruct(data, "", false)
|
||||
}
|
72
utils/printer.go
Normal file
72
utils/printer.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func shortenString(s string, length int) string {
|
||||
if len(s) > length {
|
||||
return s[:length] + "..."
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func PrintStruct(receiver interface{}, prefix string, clipContent bool) {
|
||||
// 获取结构体的反射值
|
||||
val := reflect.ValueOf(receiver)
|
||||
typ := val.Type()
|
||||
|
||||
log.Println("=========", val.Type().Name(), "=========")
|
||||
|
||||
// 检查是否是结构体
|
||||
if val.Kind() != reflect.Struct {
|
||||
log.Println("Error: Input is not a struct")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取所有字段名的最大长度
|
||||
maxFieldNameLen := 0
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
fieldName := typ.Field(i).Name
|
||||
if len(fieldName) > maxFieldNameLen {
|
||||
maxFieldNameLen = len(fieldName)
|
||||
}
|
||||
}
|
||||
maxFieldNameLen += 1
|
||||
|
||||
// 打印字段名和字段值
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fieldName := field.Name
|
||||
fieldValue := val.Field(i).Interface()
|
||||
|
||||
// 根据字段值的类型进行处理
|
||||
var output string
|
||||
switch v := fieldValue.(type) {
|
||||
case string:
|
||||
// 如果是字符串,调用 shortenString 函数缩短
|
||||
if clipContent {
|
||||
output = shortenString(v, 50)
|
||||
} else {
|
||||
output = v
|
||||
}
|
||||
case reflect.Value:
|
||||
// 如果是反射值,递归调用 PrintStruct
|
||||
if v.Kind() == reflect.Struct {
|
||||
PrintStruct(v.Interface(), prefix+" ", clipContent)
|
||||
continue
|
||||
} else if v.Kind() == reflect.Array {
|
||||
|
||||
}
|
||||
default:
|
||||
// 如果是其他类型,直接输出
|
||||
output = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
log.Printf("%s%-*s: [%s]", prefix, maxFieldNameLen, fieldName, output)
|
||||
}
|
||||
|
||||
log.Println("================================")
|
||||
}
|
Reference in New Issue
Block a user