{"id":15393857,"url":"https://github.com/mitchellh/caststructure","last_synced_at":"2026-03-16T22:31:31.573Z","repository":{"id":66228460,"uuid":"260062738","full_name":"mitchellh/caststructure","owner":"mitchellh","description":"A Go library that provides functions for downcasting types, composing values dynamically, and more.","archived":false,"fork":false,"pushed_at":"2020-05-01T04:23:12.000Z","size":15,"stargazers_count":33,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T05:59:25.723Z","etag":null,"topics":[],"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/mitchellh.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-04-29T22:49:14.000Z","updated_at":"2024-11-09T19:21:39.000Z","dependencies_parsed_at":"2023-05-01T09:45:07.129Z","dependency_job_id":null,"html_url":"https://github.com/mitchellh/caststructure","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fcaststructure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fcaststructure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fcaststructure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitchellh%2Fcaststructure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitchellh","download_url":"https://codeload.github.com/mitchellh/caststructure/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249173061,"owners_count":21224481,"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":[],"created_at":"2024-10-01T15:20:35.393Z","updated_at":"2026-03-16T22:31:31.545Z","avatar_url":"https://github.com/mitchellh.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# ⛔️ THIS DOESN'T WORK ⛔️\n\nThe functionality provided by this library unfortunately doesn't work due\nto limitations of the Go `reflect` package and runtime. I believe if these \nissues are resolved, the code here should work as-is and tests should begin\npassing. \n\nThe Go issues related to this are rooted here: https://github.com/golang/go/issues/38783\n\n# caststructure [![Godoc](https://godoc.org/github.com/mitchellh/caststructure?status.svg)](https://godoc.org/github.com/mitchellh/caststructure)\n\ncaststructure is a Go library that provides functions for downcasting types,\ncomposing values dynamically, and more. See the examples below for more details.\n\n## Installation\n\nStandard `go get`:\n\n```\n$ go get github.com/mitchellh/caststructure\n```\n\n## Usage \u0026 Example\n\nFor usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/caststructure).\n\nA quick code example is shown below that shows **downcasting**:\n\n```go\n// Three interface types.\ntype A interface { A() int }\ntype B interface { B() int }\ntype C interface { C() int }\n\n// Impl implements A, B, AND C.\ntype Impl struct {}\nfunc (Impl) A() int { return 42 }\nfunc (Impl) B() int { return 42 }\nfunc (Impl) C() int { return 42 }\n\n// We have a value of type Impl, so it implements all interfaces.\nvar value Impl\n\n// But we only want value to implement A and B, not C.\nnewValue := caststructure.Must(caststructure.Down(value, (*A)(nil), (*B)(nil)))\n_, ok := newValue.(A) // ok == true\n_, ok := newValue.(B) // ok == true\n_, ok := newValue.(C) // ok == false\n```\n\nHere is an example that shows **composing**:\n\n```go\n// Three interface types.\ntype A interface { A() int }\ntype B interface { B() int }\ntype C interface { C() int }\n\n// Implementation for A and B, respectively\ntype ImplA struct {}\nfunc (ImplA) A() int { return 42 }\n\ntype ImplB struct {}\nfunc (Impl) B() int { return 42 }\n\n// We have a value that implements A and B, separately.\nvar valueA implA\nvar valueB implB\n\n// But we want a value that implements BOTH A and B.\nnewValue := caststructure.Must(caststructure.Compose(valueA, (*A)(nil), valueB, (*B)(nil)))\n_, ok := newValue.(A) // ok == true\n_, ok := newValue.(B) // ok == true\n```\n\n## But... Why?\n\nIn general, what this library achieves can be done manually through\nexplicit type declarations. For example, composing `A` and `B` can be\ndone [explicitly like this](https://play.golang.org/p/It0NHvZt_-w). But in\ncases where the set of interfaces is large and the combinations dynamic,\ncreating explicit types becomes a burden.\n\nSome Go code allows optionally implementing interfaces to change behavior.\nFor example, code might check if `io.Closer` is implemented and call it. If\nit is not implemented, it isn't an error, it just isn't called. Taking this\nfurther, some Go code has numerous opt-in interfaces to change behavior. This\nlibrary was born out of the need to work with such APIs.\n\nFor downcasing, you might get a value that implements interfaces `A`, `B`, `C` and you\nwant to return a value that only implements `A` and `B`. If this is the only\nscenario, you can manually create a [new interface type](https://play.golang.org/p/Sgn7MhsyrXt).\nBut if the list of interfaces you want to implement is dynamic, you would\nhave to declare all combinations of the interface. This library does this\ndynamically at runtime, without panics.\n\nFor composing, you may have two separate values that implement two separate\ninterfaces `A` and `B` respectively. For example, you may have an `io.Reader`\nand an `io.Writer` but you want an `io.ReadWriter` using the two together.\nThis library can construct that ReadWriter for you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fcaststructure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitchellh%2Fcaststructure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitchellh%2Fcaststructure/lists"}