[mirror] convert json to go types olexsmir.xyz/json2go

feat: indentation

olexsmir.xyz 998d8299 917fe252

verified
+12 -4
json2go.go
··· 16 16 ) 17 17 18 18 type Transformer struct { 19 - structName string 19 + structName string 20 + currentIndent int 20 21 } 21 22 22 23 func NewTransformer() *Transformer { ··· 32 33 } 33 34 34 35 t.structName = structName 36 + t.currentIndent = 0 35 37 36 38 var input any 37 39 if err := json.Unmarshal([]byte(jsonStr), &input); err != nil { ··· 82 84 f.field = "NotNamedField" 83 85 } 84 86 87 + // increase indentation in case of building new struct 88 + t.currentIndent++ 85 89 fieldType := t.getGoType(fieldName, f.type_) 90 + t.currentIndent-- 86 91 87 92 // todo: toggle json tags generation 88 93 jsonTag := fmt.Sprintf("`json:\"%s\"`", f.field) 89 94 90 - // todo: figure out the indentation, since it might have nested struct 95 + indent := strings.Repeat("\t", t.currentIndent+1) 91 96 fields.WriteString(fmt.Sprintf( 92 - "%s %s %s\n", 97 + "%s%s %s %s\n", 98 + indent, 93 99 fieldName, 94 100 fieldType, 95 101 jsonTag, 96 102 )) 97 103 } 98 104 99 - return fmt.Sprintf("struct {\n%s}", fields.String()) 105 + return fmt.Sprintf("struct {\n%s%s}", 106 + fields.String(), 107 + strings.Repeat("\t", t.currentIndent)) 100 108 } 101 109 102 110 func (t *Transformer) getGoType(fieldName string, value any) string {
+6 -5
json2go_internal_test.go
··· 14 14 "age": float64(20), 15 15 }, 16 16 output: "struct {" + 17 - field("Age", "int") + 18 - field("Username", "string") + "\n}", 17 + field(1, "Age", "int") + 18 + field(1, "Username", "string") + 19 + "\n}", 19 20 }, 20 21 "empty slice": { 21 22 value: make([]any, 0), ··· 82 83 "active": true, 83 84 }, 84 85 output: "struct {" + 85 - field("Active", "bool", "active") + 86 + field(1, "Active", "bool", "active") + 86 87 "\n}", 87 88 }, 88 89 "with no named field": { 89 90 input: map[string]any{"": "user"}, 90 91 output: "struct {" + 91 - field("NotNamedField", "string", "NotNamedField") + 92 + field(1, "NotNamedField", "string", "NotNamedField") + 92 93 "\n}", 93 94 }, 94 95 } ··· 113 114 "struct": { 114 115 input: map[string]any{"field": false}, 115 116 output: c + "struct {" + 116 - field("Field", "bool") + "\n}", 117 + field(1, "Field", "bool") + "\n}", 117 118 }, 118 119 "slice": { 119 120 input: []any{"asdf", "jkl;"},
+22 -21
json2go_test.go
··· 8 8 "testing" 9 9 ) 10 10 11 - func field(name, type_ string, json_ ...string) string { 11 + func field(indentLvl int, name, type_ string, json_ ...string) string { 12 + indent := strings.Repeat("\t", indentLvl) 12 13 if strings.Contains(type_, "struct") { 13 - return fmt.Sprintf("\n%s %s", name, type_) 14 + return fmt.Sprintf("\n%s%s %s", indent, name, type_) 14 15 } 15 16 16 17 tag := strings.ToLower(name) 17 18 if len(json_) == 1 { 18 19 tag = json_[0] 19 20 } 20 - return fmt.Sprintf("\n%s %s `json:\"%s\"`", name, type_, tag) 21 + return fmt.Sprintf("\n%s%s %s `json:\"%s\"`", indent, name, type_, tag) 21 22 } 22 23 23 24 func TestTransformer_Transform(t *testing.T) { ··· 30 31 "simple object": { 31 32 input: `{"name": "Olex", "active": true, "age": 420}`, 32 33 output: "type Out struct {" + 33 - field("Active", "bool") + 34 - field("Age", "int") + 35 - field("Name", "string") + 34 + field(1, "Active", "bool") + 35 + field(1, "Age", "int") + 36 + field(1, "Name", "string") + 36 37 "\n}", 37 38 }, 38 39 "invalid json": { ··· 54 55 "snake_case to CamelCase": { 55 56 input: `{"first_name": "Bob", "last_name": "Bobberson"}`, 56 57 output: "type Out struct {" + 57 - field("FirstName", "string", "first_name") + 58 - field("LastName", "string", "last_name") + 58 + field(1, "FirstName", "string", "first_name") + 59 + field(1, "LastName", "string", "last_name") + 59 60 "\n}", 60 61 }, 61 62 "nested object and array": { 62 63 input: `{"user": {"name": "Alice", "score": 95.5}, "tags": ["go", "json"]}`, 63 64 output: "type Out struct {" + 64 - field("Tags", "[]string") + 65 - field("User", "struct {") + 66 - field("Name", "string") + 67 - field("Score", "float64") + 68 - "\n} `json:\"user\"`" + 65 + field(1, "Tags", "[]string") + 66 + field(1, "User", "struct {") + 67 + field(2, "Name", "string") + 68 + field(2, "Score", "float64") + 69 + "\n\t} `json:\"user\"`" + 69 70 "\n}", 70 71 }, 71 72 "empty nested object": { 72 73 input: `{"user": {}}`, 73 74 output: "type Out struct {" + 74 - field("User", "struct {") + 75 - "\n} `json:\"user\"`" + 75 + field(1, "User", "struct {") + 76 + "\n\t} `json:\"user\"`" + 76 77 "\n}", 77 78 }, 78 79 "array of object": { 79 80 input: `[{"name": "John"}, {"name": "Jane"}]`, 80 81 output: "type Out []struct {" + 81 - field("Name", "string") + 82 + field(1, "Name", "string") + 82 83 "\n}", 83 84 }, 84 85 "empty array": { 85 86 input: `{"items": []}`, 86 87 output: "type Out struct {" + 87 - field("Items", "[]any") + 88 + field(1, "Items", "[]any") + 88 89 "\n}", 89 90 }, 90 91 "null": { 91 92 input: `{"item": null}`, 92 93 output: `type Out struct {` + 93 - field("Item", "any") + 94 + field(1, "Item", "any") + 94 95 "\n}", 95 96 }, 96 97 "numbers": { 97 98 input: `{"pos": 123, "neg": -321, "float": 420.69}`, 98 99 output: "type Out struct {" + 99 - field("Float", "float64") + 100 - field("Neg", "int") + 101 - field("Pos", "int") + 100 + field(1, "Float", "float64") + 101 + field(1, "Neg", "int") + 102 + field(1, "Pos", "int") + 102 103 "\n}", 103 104 }, 104 105 }