{"id":13671844,"url":"https://github.com/NyxCode/proxy-enum","last_synced_at":"2025-04-27T18:31:49.978Z","repository":{"id":38201672,"uuid":"259754694","full_name":"NyxCode/proxy-enum","owner":"NyxCode","description":"Emulate dynamic dispatch and sealed classes using a proxy enum, which defers all method calls to its variants.","archived":false,"fork":false,"pushed_at":"2021-06-06T05:48:14.000Z","size":12,"stargazers_count":19,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-21T09:53:41.872Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NyxCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-28T21:24:43.000Z","updated_at":"2024-04-19T01:13:50.000Z","dependencies_parsed_at":"2022-09-04T14:12:59.647Z","dependency_job_id":null,"html_url":"https://github.com/NyxCode/proxy-enum","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/NyxCode%2Fproxy-enum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NyxCode%2Fproxy-enum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NyxCode%2Fproxy-enum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NyxCode%2Fproxy-enum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NyxCode","download_url":"https://codeload.github.com/NyxCode/proxy-enum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251187316,"owners_count":21549618,"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-08-02T09:01:20.153Z","updated_at":"2025-04-27T18:31:47.672Z","avatar_url":"https://github.com/NyxCode.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# proxy-enum\n[![Crate](https://img.shields.io/crates/v/proxy-enum.svg)](https://crates.io/crates/proxy-enum)\n[![API](https://docs.rs/proxy-enum/badge.svg)](https://docs.rs/proxy-enum)\n\nEmulate dynamic dispatch and [\"sealed classes\"](https://kotlinlang.org/docs/reference/sealed-classes.html) using a proxy enum, which defers all method calls to its variants.\n\n## Introduction\nIn rust, dynamic dispatch is done using trait objects (`dyn Trait`).\nThey enable us to have runtime polymorphism, a way of expressing that a type implements a\ncertain trait while ignoring its concrete implementation.\n\n```rust\nlet animal: \u0026dyn Animal = random_animal();\nanimal.feed(); // may print \"mew\", \"growl\" or \"squeak\"\n```\n\nTrait objects come with a downside though:\ngetting a concrete implementation back from a trait object (downcasting) is painfull.\n(see [std::any::Any])\n\nIf you know there are only a finite number of implentations to work with, an `enum` might be\nbetter at expressing such a relationship:\n```rust\nenum Animal {\n    Cat(Cat),\n    Lion(Lion),\n    Mouse(Mouse)\n}\n\nmatch random_animal() {\n    Animal::Cat(cat) =\u003e cat.feed(),\n    Animal::Lion(lion) =\u003e lion.feed(),\n    Animal::Mouse(mouse) =\u003e mouse.feed()\n}\n```\nSome languages have special support for such types, like Kotlin with so called \"sealed classes\".\n\nRust, however, does *not*.\n\n`proxy-enum` simplifies working with such types using procedural macros.\n\n## Usage\n```rust\n#[proxy_enum::proxy(Animal)]\nmod proxy {\n    enum Animal {\n        Cat(Cat),\n        Lion(Lion),\n        Mouse(Mouse)\n    }\n\n    impl Animal {\n        #[implement]\n        fn feed(\u0026self) {}\n    }\n}\n```\nThis will expand to:\n```rust\nmod proxy {\n    enum Animal {\n        Cat(Cat),\n        Lion(Lion),\n        Mouse(Mouse)\n    }\n\n    impl Animal {\n        fn feed(\u0026self) {\n            match self {\n                Animal::Cat(cat) =\u003e cat.feed(),\n                Animal::Lion(lion) =\u003e lion.feed(),\n                Animal::Mouse(mouse) =\u003e mouse.feed()\n            }\n        }\n    }  \n\n    impl From\u003cCat\u003e for Animal { /* ... */ }\n    impl From\u003cLion\u003e for Animal { /* ... */ }\n    impl From\u003cMouse\u003e for Animal { /* ... */ }\n}\n```\nThis, however, will only compile if `Cat`, `Lion` and `Mouse` all have a method called `feed`.\nSince rust has traits to express common functionality, trait implentations can be generated too:\n```rust\n#[proxy_enum::proxy(Animal)]\nmod proxy {\n    enum Animal {\n        Cat(Cat),\n        Lion(Lion),\n        Mouse(Mouse)\n    }\n\n    trait Eat {\n        fn feed(\u0026self);\n    }\n\n    #[implement]\n    impl Eat for Animal {}\n}\n```\nSince the macro has to know which methods the trait contains, it has to be defined within the\nmodule. However, implementations for external traits can be generated too:\n\n```rust\n#[proxy_enum::proxy(Animal)]\nmod proxy {\n    enum Animal {\n        Cat(Cat),\n        Lion(Lion),\n        Mouse(Mouse)\n    }\n\n    #[external(std::string::ToString)]\n    trait ToString {\n        fn to_string(\u0026self) -\u003e String;\n    }\n\n    #[implement]\n    impl std::string::ToString for Animal {}\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNyxCode%2Fproxy-enum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNyxCode%2Fproxy-enum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNyxCode%2Fproxy-enum/lists"}