{"id":36784954,"url":"https://github.com/desertbit/options","last_synced_at":"2026-01-12T13:20:13.157Z","repository":{"id":81341701,"uuid":"270949858","full_name":"desertbit/options","owner":"desertbit","description":"Suggests a design guideline for Config/Option structs","archived":false,"fork":false,"pushed_at":"2021-01-26T15:38:17.000Z","size":16,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2023-12-16T05:19:36.434Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/desertbit.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":"2020-06-09T08:46:54.000Z","updated_at":"2024-06-19T07:52:21.223Z","dependencies_parsed_at":"2023-10-29T18:15:08.599Z","dependency_job_id":null,"html_url":"https://github.com/desertbit/options","commit_stats":null,"previous_names":[],"tags_count":4,"template":null,"template_full_name":null,"purl":"pkg:github/desertbit/options","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Foptions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Foptions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Foptions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Foptions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/desertbit","download_url":"https://codeload.github.com/desertbit/options/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Foptions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":[],"created_at":"2026-01-12T13:20:06.516Z","updated_at":"2026-01-12T13:20:12.196Z","avatar_url":"https://github.com/desertbit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Suggests a design guideline for Config/Option structs.\n\n```go\ntype Options struct {\n    NumWorkers int `yaml:\"num-workers,omitempty\"`\n    Name string `yaml:\"name,omitempty\"`\n    ConfThreshold int `yaml:\"conf-threshold,omitempty\"`\n}\n\nfunc DefaultOptions() Options {\n    return Options{\n        NumWorkers: 8,\n        Name: \"testName\",\n        ConfThreshold: 0.85,\n    }\n}\n\nfunc (o Options) Save(path string) error {\n    // Do not serialize any values that match the default values.\n    // This way, only changes are reflected in the options file.\n    // The Options struct itself is not altered, since the receiver\n    // is not a pointer.\n    err = options.StripDefaults(\u0026o, DefaultOptions())\n    if err != nil {\n        return err\n    }\n\n    // ... yaml marshal and write to file ...\n}\n```\n\nThe main concept is **simplicity**. One simple Options struct combined with one constructor that returns the default settings.\nBy not serializing any default values (`StripDefaults`), we keep the written file tidy and only list **changes to the defaults**.\n\nIn case a **slice** or **map** is used in the config, whose elements are structs again, it is not possible to state real default values.\nInstead, one should iterate over the options after parsing and set default values on each of the elements.\n\n```go\ntype Options struct {\n    NumWorkers int `yaml:\"num-workers,omitempty\"`\n    Name string `yaml:\"name,omitempty\"`\n    ConfThreshold int `yaml:\"conf-threshold,omitempty\"`\n    Sl []Nested `yaml:\"sl,omitempty\"`\n}\n\ntype Nested struct {\n    Test int `yaml:\"test,omitempty\"`\n}\n\nfunc DefaultNestedOptions() Nested {\n    return Nested{Test: 5}\n}\n\nfunc ParseOptionsFromFile(path string) (o Options, err error) {\n\to = DefaultOptions(path)\n\n\t// Read data from file.\n\tdata, err := ioutil.ReadFile(path)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Unmarshal the data.\n\terr = yaml.UnmarshalStrict(data, \u0026o)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Iterate over the nested options and set default values.\n\tdn := DefaultNestedOptions()\n\tfor i := range o.Sl {\n\t    err = options.SetDefaults(o.Sl[i], dn)\n\t    if err != nil {\n\t        return\n\t    }\n\t}\n\n\treturn\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesertbit%2Foptions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdesertbit%2Foptions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesertbit%2Foptions/lists"}