{"id":38935239,"url":"https://github.com/etecs-ru/typedyaml","last_synced_at":"2026-01-17T15:47:43.954Z","repository":{"id":54451010,"uuid":"282596232","full_name":"etecs-ru/typedyaml","owner":"etecs-ru","description":" YAML with polymorphic types in Go with this code generation tool.","archived":false,"fork":false,"pushed_at":"2023-02-25T07:32:06.000Z","size":158,"stargazers_count":9,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-19T19:48:17.545Z","etag":null,"topics":["codegen","codegenerator","configuration","go","polymorphic","yaml"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/etecs-ru/typedyaml","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/etecs-ru.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-26T07:09:05.000Z","updated_at":"2024-02-23T17:17:30.000Z","dependencies_parsed_at":"2024-06-19T19:06:54.206Z","dependency_job_id":"656279f5-bf74-4efd-a7f3-0a385f86079c","html_url":"https://github.com/etecs-ru/typedyaml","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/etecs-ru/typedyaml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etecs-ru%2Ftypedyaml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etecs-ru%2Ftypedyaml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etecs-ru%2Ftypedyaml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etecs-ru%2Ftypedyaml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/etecs-ru","download_url":"https://codeload.github.com/etecs-ru/typedyaml/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etecs-ru%2Ftypedyaml/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28511851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T13:38:16.342Z","status":"ssl_error","status_checked_at":"2026-01-17T13:37:44.060Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["codegen","codegenerator","configuration","go","polymorphic","yaml"],"created_at":"2026-01-17T15:47:43.804Z","updated_at":"2026-01-17T15:47:43.901Z","avatar_url":"https://github.com/etecs-ru.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# typedyaml\n\n\u003cimg align=\"right\" src=\"https://i.ibb.co/qxTM0sP/Gopher-puzzled.png\"\u003e\n\nA lightweight code generator for Go alleviates YAML marshalling/unmarshalling unrelated structs in typed fashion. Depends on [github.com/goccy/go-yaml](https://github.com/goccy/go-yaml) allowing such benefits as [fields validation](https://github.com/goccy/go-yaml/blob/868d322819b933bce2a46cfa2951c08706600f14/validate_test.go#L75).\n\n## Badges\n\n![Build Status](https://github.com/golangci/golangci-lint/workflows/CI/badge.svg)\n[![Go Reference](https://pkg.go.dev/badge/github.com/etecs-ru/typedyaml.svg)](https://pkg.go.dev/github.com/etecs-ru/typedyaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/etecs-ru/typedyaml)](https://goreportcard.com/report/github.com/etecs-ru/typedyaml)\n[![codecov](https://codecov.io/gh/etecs-ru/typedyaml/branch/master/graph/badge.svg)](https://codecov.io/gh/etecs-ru/typedyaml)\n[![License](https://img.shields.io/github/license/etecs-ru/typedyaml)](/LICENSE)\n\nImagine, that you need to configure several instances of some service, each of a different kind\nusing a YAML object with some key `Config`. \nThe value of this field can correspond to two structs of your Go program: `FooConfig` and `BarConfig`.\nSo, the field `Config` in your struct must be able to hold a value of two possible types.\nIn this case, you have the following options:\n\n1. You can declare field `Config` as `interface{}` and somehow determine what type you should expect, assign an object of this type to `Config` \nand then unmarshal an object.\n1. You can unmarshal field `Config` separately.\n1. You can implement custom `MarshalYAML`/`UnmarshalYAML` for the third type that automatically will handle these cases.\n\nThis package provides means to generate all boilerplate code for the third case.\n\n## Usage\n\n```sh\ntypedyaml [OPTION] NAME...\n```\n\nOptions:\n\n* `-interface` string\n\n\tName of the interface that encompasses all types.\n\n* `-output` string\n\n\tOutput path where generated code should be saved.\n\n* `-package` string\n\n\tThe package name in the generated file (default to GOPACKAGE).\n\n* `-typed` string\n\n\tThe name of the struct that will be used for typed interface (default to `{{interface}}{{Typed}}`).\n\nEach name in position argument should be the name of the struct. \nYou can set an alias for struct name like this: `foo=*FooConfig`.\n\n## Example\n\nSee code in the [/example](https://github.com/etecs-ru/typedyaml/tree/master/example) folder.\n\nFor example, you have some microservice that serves orders to users and use gateways to other microservices that provides it. You need to configure it in one YAML file in a smart way.\n\nYou define `UsersGateway` and `OrdersGateway` structures in our Go code, like:\n\n```go\npackage config\n\nimport \"time\"\n\ntype UsersGateway struct {\n\tEnabled            bool   `yaml:\"enabled\"`\n\tHost               string `yaml:\"host\"`\n\tPort               int    `yaml:\"port\"`\n\tUser               string `yaml:\"user\"`\n\tSecurityDescriptor string `yaml:\"security_descriptor\"`\n}\n\ntype OrdersGateway struct {\n\tEnabled bool               `yaml:\"enabled\"`\n\tKafka   KafkaConfiguration `yaml:\"kafka\"`\n}\n\ntype KafkaConfiguration struct {\n\tHosts          []string      `yaml:\"hosts\" validate:\"required\"`\n\tTopics         []string      `yaml:\"topics\" validate:\"required\"`\n\tGroupID        string        `yaml:\"group_id\" validate:\"required\"`\n\tClientID       string        `yaml:\"client_id\"`\n\tConnectBackoff time.Duration `yaml:\"connect_backoff\" validate:\"min=0\"`\n\tConsumeBackoff time.Duration `yaml:\"consume_backoff\" validate:\"min=0\"`\n\tWaitClose      time.Duration `yaml:\"wait_close\" validate:\"min=0\"`\n\tMaxWaitTime    time.Duration `yaml:\"max_wait_time\"`\n\tIsolationLevel int           `yaml:\"isolation_level\"`\n\tUsername       string        `yaml:\"username\"`\n\tPassword       string        `yaml:\"password\"`\n}\n```\n\nSo you need to group these pieces together in some `MicroserviceConfig` structure and want to read it from YAML file.\n\nWe propose to implement polymorphic type `Gateway` using this code generation tool.\n\nFirst, you must declare an interface that will hold either of these structs. The interface must have the method `TypedYAML` with a signature holding name of your container struct with a `Typed` suffix, like *Gateway:GatewayTyped*. This method will advise the compiler to work with types.\n\nLet's see:\n\n```go\npackage config \n\n//go:generate go run github.com/etecs-ru/typedyaml -package config -interface Gateway users=UsersGateway orders=OrdersGateway\ntype Gateway interface {\n\tTypedYAML(*GatewayTyped) string\n}\n```\nNow, run `go generate`.\nGenerated struct `GatewayTyped` will have special implemented methods `MarshalYAML`/`UnmarshalYAML`. `GatewayTyped` could be used as a single instance, or in a slice. Adding configuration for new gateways now working like a charm -- just add its type to code generation argument and regenerate the code.\n\nLet us write some configuration example:\n\n```yaml\ntags:\n  key: value\ngateway:\n  type: users\n  value:\n    enabled: false\n    host: internal-users.microservice.lan\n    port: 8443\n    user: robot\n    security_descriptor: SY\ngateways:\n- type: users\n  value:\n    enabled: true\n    host: external-users.microservice.lan\n    port: 8443\n    user: robot\n    security_descriptor: SY\n- type: orders\n  value:\n    enabled: true\n    kafka:\n      hosts:\n        - host-a:7891\n        - host-b:7892\n      topics:\n        - topic-a\n        - topic-b\n        - topic-c\n      group_id: gid01\n      client_id: cid01\n      connect_backoff: 1000000000\n      consume_backoff: 1000000000\n      wait_close: 1000000000\n      max_wait_time: 1000000000\n      isolation_level: 0\n      username: user\n      password: password\n```\n\n\nYou can use generated code like this:\n\n```go\npackage config\n\nimport (\n\t\"io/ioutil\"\n\n\t\"github.com/goccy/go-yaml\"\n)\n\ntype MicroserviceConfig struct {\n\tTags     map[string]string `yaml:\"tags\"`\n\tGateway  GatewayTyped      `yaml:\"gateway\"`\n\tGateways []GatewayTyped    `yaml:\"gateways\"`\n}\n\nfunc ReadMicroserviceConfigFromFile(path string) (*MicroserviceConfig, error) {\n\tb, err := ioutil.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar cfg MicroserviceConfig\n\tif err = yaml.Unmarshal(b, \u0026cfg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn \u0026cfg, nil\n}\n\nfunc WriteMicroserviceConfigToFile(cfg MicroserviceConfig, path string) error {\n\tb, err := yaml.Marshal(cfg)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn ioutil.WriteFile(path, b, 0644)\n}\n\n```\n\n## Contributing\n\nBug reports, test cases, and code contributions are more than welcome.\nPlease refer to the [contribution guidelines](./CONTRIBUTING.md).\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetecs-ru%2Ftypedyaml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fetecs-ru%2Ftypedyaml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetecs-ru%2Ftypedyaml/lists"}