commit 3da9e929b536df400ca72fb81e24685c0c001aef Author: WriterPass Date: Mon Feb 3 12:48:59 2025 +0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cffcb3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.json \ No newline at end of file diff --git a/core/data-clip-builder.go b/core/data-clip-builder.go new file mode 100644 index 0000000..63ac09e --- /dev/null +++ b/core/data-clip-builder.go @@ -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_, + } +} diff --git a/core/data-clip.go b/core/data-clip.go new file mode 100644 index 0000000..56568d0 --- /dev/null +++ b/core/data-clip.go @@ -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) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..6d1c26d --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module json-dataloader-golang + +go 1.23 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/main.go new file mode 100644 index 0000000..0b189e6 --- /dev/null +++ b/main.go @@ -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) +} diff --git a/utils/printer.go b/utils/printer.go new file mode 100644 index 0000000..10db66a --- /dev/null +++ b/utils/printer.go @@ -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("================================") +}