{"id":18527141,"url":"https://github.com/ompluscator/dynamic-struct","last_synced_at":"2025-05-16T08:04:35.471Z","repository":{"id":37335115,"uuid":"164148192","full_name":"Ompluscator/dynamic-struct","owner":"Ompluscator","description":"Golang package for editing struct's fields during runtime and mapping structs to other structs.","archived":false,"fork":false,"pushed_at":"2024-01-27T21:54:19.000Z","size":44,"stargazers_count":713,"open_issues_count":3,"forks_count":83,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-05-16T08:04:29.223Z","etag":null,"topics":["dynamic","go","golang","runtime","structs"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ompluscator.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-04T19:44:40.000Z","updated_at":"2025-05-14T19:38:58.000Z","dependencies_parsed_at":"2024-11-06T17:55:02.050Z","dependency_job_id":"4455e5e0-de8a-43e1-96d4-c9986e60096c","html_url":"https://github.com/Ompluscator/dynamic-struct","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ompluscator%2Fdynamic-struct","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ompluscator%2Fdynamic-struct/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ompluscator%2Fdynamic-struct/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ompluscator%2Fdynamic-struct/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ompluscator","download_url":"https://codeload.github.com/Ompluscator/dynamic-struct/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493378,"owners_count":22080126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic","go","golang","runtime","structs"],"created_at":"2024-11-06T17:53:24.532Z","updated_at":"2025-05-16T08:04:30.459Z","avatar_url":"https://github.com/Ompluscator.png","language":"Go","readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/Ompluscator/dynamic-struct.svg)](https://pkg.go.dev/github.com/Ompluscator/dynamic-struct)\n![Coverage](https://img.shields.io/badge/Coverage-92.6%25-brightgreen)\n[![Go Report Card](https://goreportcard.com/badge/github.com/ompluscator/dynamic-struct)](https://goreportcard.com/report/github.com/ompluscator/dynamic-struct)\n\n# Golang dynamic struct\n\nPackage dynamic struct provides possibility to dynamically, in runtime,\nextend or merge existing defined structs or to provide completely new struct.\n\nMain features:\n* Building completely new struct in runtime\n* Extending existing struct in runtime\n* Merging multiple structs in runtime\n* Adding new fields into struct\n* Removing existing fields from struct\n* Modifying fields' types and tags\n* Easy reading of dynamic structs\n* Mapping dynamic struct with set values to existing struct\n* Make slices and maps of dynamic structs\n\nWorks out-of-the-box with:\n* https://github.com/go-playground/form\n* https://github.com/go-playground/validator\n* https://github.com/leebenson/conform\n* https://golang.org/pkg/encoding/json/\n* ...\n\n## Benchmarks\n\nEnvironment:\n* MacBook Pro (13-inch, Early 2015), 2,7 GHz Intel Core i5\n* go version go1.11 darwin/amd64\n\n```\ngoos: darwin\ngoarch: amd64\npkg: github.com/ompluscator/dynamic-struct\nBenchmarkClassicWay_NewInstance-4                 2000000000     0.34 ns/op\nBenchmarkNewStruct_NewInstance-4                    10000000      141 ns/op\nBenchmarkNewStruct_NewInstance_Parallel-4           20000000     89.6 ns/op\nBenchmarkExtendStruct_NewInstance-4                 10000000      135 ns/op\nBenchmarkExtendStruct_NewInstance_Parallel-4        20000000     89.5 ns/op\nBenchmarkMergeStructs_NewInstance-4                 10000000      140 ns/op\nBenchmarkMergeStructs_NewInstance_Parallel-4        20000000     94.3 ns/op\n```\n\n## Add new struct\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\nfunc main() {\n\tinstance := dynamicstruct.NewStruct().\n\t\tAddField(\"Integer\", 0, `json:\"int\"`).\n\t\tAddField(\"Text\", \"\", `json:\"someText\"`).\n\t\tAddField(\"Float\", 0.0, `json:\"double\"`).\n\t\tAddField(\"Boolean\", false, \"\").\n\t\tAddField(\"Slice\", []int{}, \"\").\n\t\tAddField(\"Anonymous\", \"\", `json:\"-\"`).\n\t\tBuild().\n\t\tNew()\n\n\tdata := []byte(`\n{\n    \"int\": 123,\n    \"someText\": \"example\",\n    \"double\": 123.45,\n    \"Boolean\": true,\n    \"Slice\": [1, 2, 3],\n    \"Anonymous\": \"avoid to read\"\n}\n`)\n\n\terr := json.Unmarshal(data, \u0026instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tdata, err = json.Marshal(instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Println(string(data))\n\t// Out:\n\t// {\"int\":123,\"someText\":\"example\",\"double\":123.45,\"Boolean\":true,\"Slice\":[1,2,3]}\n}\n```\n\n## Extend existing struct\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\ntype Data struct {\n\tInteger int `json:\"int\"`\n}\n\nfunc main() {\n\tinstance := dynamicstruct.ExtendStruct(Data{}).\n\t\tAddField(\"Text\", \"\", `json:\"someText\"`).\n\t\tAddField(\"Float\", 0.0, `json:\"double\"`).\n\t\tAddField(\"Boolean\", false, \"\").\n\t\tAddField(\"Slice\", []int{}, \"\").\n\t\tAddField(\"Anonymous\", \"\", `json:\"-\"`).\n\t\tBuild().\n\t\tNew()\n\n\tdata := []byte(`\n{\n    \"int\": 123,\n    \"someText\": \"example\",\n    \"double\": 123.45,\n    \"Boolean\": true,\n    \"Slice\": [1, 2, 3],\n    \"Anonymous\": \"avoid to read\"\n}\n`)\n\n\terr := json.Unmarshal(data, \u0026instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tdata, err = json.Marshal(instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Println(string(data))\n\t// Out:\n\t// {\"int\":123,\"someText\":\"example\",\"double\":123.45,\"Boolean\":true,\"Slice\":[1,2,3]}\n}\n```\n\n## Merge existing structs\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\ntype DataOne struct {\n\tInteger int     `json:\"int\"`\n\tText    string  `json:\"someText\"`\n\tFloat   float64 `json:\"double\"`\n}\n\ntype DataTwo struct {\n\tBoolean bool\n\tSlice []int\n\tAnonymous string `json:\"-\"`\n}\n\nfunc main() {\n\tinstance := dynamicstruct.MergeStructs(DataOne{}, DataTwo{}).\n\t\tBuild().\n\t\tNew()\n\n\tdata := []byte(`\n{\n\"int\": 123,\n\"someText\": \"example\",\n\"double\": 123.45,\n\"Boolean\": true,\n\"Slice\": [1, 2, 3],\n\"Anonymous\": \"avoid to read\"\n}\n`)\n\n\terr := json.Unmarshal(data, \u0026instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tdata, err = json.Marshal(instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Println(string(data))\n\t// Out:\n\t// {\"int\":123,\"someText\":\"example\",\"double\":123.45,\"Boolean\":true,\"Slice\":[1,2,3]}\n}\n```\n\n## Read dynamic struct\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\ntype DataOne struct {\n\tInteger int     `json:\"int\"`\n\tText    string  `json:\"someText\"`\n\tFloat   float64 `json:\"double\"`\n}\n\ntype DataTwo struct {\n\tBoolean bool\n\tSlice []int\n\tAnonymous string `json:\"-\"`\n}\n\nfunc main() {\n\tinstance := dynamicstruct.MergeStructs(DataOne{}, DataTwo{}).\n\t\tBuild().\n\t\tNew()\n\n\tdata := []byte(`\n{\n\"int\": 123,\n\"someText\": \"example\",\n\"double\": 123.45,\n\"Boolean\": true,\n\"Slice\": [1, 2, 3],\n\"Anonymous\": \"avoid to read\"\n}\n`)\n\n\terr := json.Unmarshal(data, \u0026instance)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\treader := dynamicstruct.NewReader(instance)\n\n\tfmt.Println(\"Integer\", reader.GetField(\"Integer\").Int())\n\tfmt.Println(\"Text\", reader.GetField(\"Text\").String())\n\tfmt.Println(\"Float\", reader.GetField(\"Float\").Float64())\n\tfmt.Println(\"Boolean\", reader.GetField(\"Boolean\").Bool())\n\tfmt.Println(\"Slice\", reader.GetField(\"Slice\").Interface().([]int))\n\tfmt.Println(\"Anonymous\", reader.GetField(\"Anonymous\").String())\n\n\tvar dataOne DataOne\n\terr = reader.ToStruct(\u0026dataOne)\n\tfmt.Println(err, dataOne)\n\n\tvar dataTwo DataTwo\n\terr = reader.ToStruct(\u0026dataTwo)\n\tfmt.Println(err, dataTwo)\n\t// Out:\n\t// Integer 123\n\t// Text example\n\t// Float 123.45\n\t// Boolean true\n\t// Slice [1 2 3]\n\t// Anonymous\n\t// \u003cnil\u003e {123 example 123.45}\n\t// \u003cnil\u003e {true [1 2 3] }\n}\n```\n\n## Make a slice of dynamic struct\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\ntype Data struct {\n\tInteger   int     `json:\"int\"`\n\tText      string  `json:\"someText\"`\n\tFloat     float64 `json:\"double\"`\n\tBoolean   bool\n\tSlice     []int\n\tAnonymous string `json:\"-\"`\n}\n\nfunc main() {\n\tdefinition := dynamicstruct.ExtendStruct(Data{}).Build()\n\n\tslice := definition.NewSliceOfStructs()\n\n\tdata := []byte(`\n[\n\t{\n\t\t\"int\": 123,\n\t\t\"someText\": \"example\",\n\t\t\"double\": 123.45,\n\t\t\"Boolean\": true,\n\t\t\"Slice\": [1, 2, 3],\n\t\t\"Anonymous\": \"avoid to read\"\n\t}\n]\n`)\n\n\terr := json.Unmarshal(data, \u0026slice)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tdata, err = json.Marshal(slice)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Println(string(data))\n\t// Out:\n\t// [{\"Boolean\":true,\"Slice\":[1,2,3],\"int\":123,\"someText\":\"example\",\"double\":123.45}]\n\n\treader := dynamicstruct.NewReader(slice)\n\treadersSlice := reader.ToSliceOfReaders()\n\tfor k, v := range readersSlice {\n\t\tvar value Data\n\t\terr := v.ToStruct(\u0026value)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tfmt.Println(k, value)\n\t}\n\t// Out:\n\t// 0 {123 example 123.45 true [1 2 3] }\n}\n\n```\n\n## Make a map of dynamic struct\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ompluscator/dynamic-struct\"\n)\n\ntype Data struct {\n\tInteger   int     `json:\"int\"`\n\tText      string  `json:\"someText\"`\n\tFloat     float64 `json:\"double\"`\n\tBoolean   bool\n\tSlice     []int\n\tAnonymous string `json:\"-\"`\n}\n\nfunc main() {\n\tdefinition := dynamicstruct.ExtendStruct(Data{}).Build()\n\n\tmapWithStringKey := definition.NewMapOfStructs(\"\")\n\n\tdata := []byte(`\n{\n\t\"element\": {\n\t\t\"int\": 123,\n\t\t\"someText\": \"example\",\n\t\t\"double\": 123.45,\n\t\t\"Boolean\": true,\n\t\t\"Slice\": [1, 2, 3],\n\t\t\"Anonymous\": \"avoid to read\"\n\t}\n}\n`)\n\n\terr := json.Unmarshal(data, \u0026mapWithStringKey)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tdata, err = json.Marshal(mapWithStringKey)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Println(string(data))\n\t// Out:\n\t// {\"element\":{\"int\":123,\"someText\":\"example\",\"double\":123.45,\"Boolean\":true,\"Slice\":[1,2,3]}}\n\n\treader := dynamicstruct.NewReader(mapWithStringKey)\n\treadersMap := reader.ToMapReaderOfReaders()\n\tfor k, v := range readersMap {\n\t\tvar value Data\n\t\terr := v.ToStruct(\u0026value)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tfmt.Println(k, value)\n\t}\n\t// Out:\n\t// element {123 example 123.45 true [1 2 3] }\n}\n\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fompluscator%2Fdynamic-struct","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fompluscator%2Fdynamic-struct","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fompluscator%2Fdynamic-struct/lists"}