{"id":21736370,"url":"https://github.com/kyza/orderless","last_synced_at":"2025-07-07T07:06:58.185Z","repository":{"id":163946198,"uuid":"639385063","full_name":"Kyza/orderless","owner":"Kyza","description":"Generates macros for you that allow you to use orderless/named functions in Rust.","archived":false,"fork":false,"pushed_at":"2023-06-02T13:32:34.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2025-06-13T16:41:42.760Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://crates.io/crates/orderless","language":"Rust","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/Kyza.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":"2023-05-11T11:15:40.000Z","updated_at":"2023-05-11T11:51:22.000Z","dependencies_parsed_at":"2023-07-21T19:40:00.554Z","dependency_job_id":null,"html_url":"https://github.com/Kyza/orderless","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Kyza/orderless","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kyza%2Forderless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kyza%2Forderless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kyza%2Forderless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kyza%2Forderless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kyza","download_url":"https://codeload.github.com/Kyza/orderless/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kyza%2Forderless/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259747425,"owners_count":22905323,"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-11-26T05:18:30.430Z","updated_at":"2025-07-07T07:06:58.158Z","avatar_url":"https://github.com/Kyza.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# orderless!\r\n\r\n`orderless` generates macros for you that allow you to use orderless/named functions in Rust.\r\n\r\n```rs\r\n#[make_orderless(defs(a = 2))]\r\nfn add(a: usize, b: usize) -\u003e usize {\r\n\ta + b\r\n}\r\n\r\n// Compiles to add(2, 2) for no runtime performance hit!\r\nadd!(b = 2); // 4\r\n```\r\n\r\n## Features\r\n\r\n- [x] Attribute macro.\r\n- [x] Procedural macro.\r\n- [x] Paths to functions (functions from crates and `impl`).\r\n- [x] Default argument values.\r\n\t- [x] Identifiers.\r\n\t- [x] Expressions.\r\n\t- [x] `const` and `static` variables.\r\n\t- [x] Optionally don't provide a default value.\r\n- [x] Shortcut identical name and value to just the name. `a = a` to `a`.\r\n- [x] Attribute macro `impl_orderless` for `make_orderless` in `impl` blocks.\r\n\r\n## Docs\r\n\r\nDocumentation is provided on [docs.rs](https://docs.rs/orderless).\r\n\r\n## How does it work?\r\n\r\n### `call_orderless!`\r\n\r\n`call_orderless!` is the proc macro that does all the heavy lifting. It takes a bunch of info such as the function's name, the order of the arguments, and the default values.\r\n\r\n```rs\r\ncall_orderless! {\r\n\tfunc = two,\r\n\torder(a, b),\r\n\tdefs(a = false, b = false),\r\n\targs(a = true, b = false),\r\n}\r\n```\r\n\r\nAs you can see, using it on its own is pretty pointless. But it's perfect for other macros to pass info they have to it.\r\n\r\n### `create_orderless!`\r\n\r\n`create_orderless!` is another helper macro. It simplifies the process of writing `call_orderless!` by generating a `macro_rules!` macro which has most of the info built in. \r\n\r\n```rs\r\ncreate_orderless! {\r\n\tfunc = two,\r\n\torder(a, b),\r\n\tdefs(a = false, b = false)\r\n}\r\n\r\n// Generates...\r\n// Note `order(...)` disappears because it's integrated into `defs(...)` by `create_orderless!`.\r\nmacro_rules! two {\r\n\t( $($arg_name:ident $(= $arg_value:expr)?),*$(,)? ) =\u003e {\r\n\t\t::orderless::call_orderless!(\r\n\t\t\tfunc = two,\r\n\t\t\tdefs(a = false, b = false),\r\n\t\t\targs($($arg_name $(= $arg_value)?),*),\r\n\t\t)\r\n\t};\r\n\t() =\u003e {\r\n\t\t::orderless::call_orderless!(\r\n\t\t\tfunc = two,\r\n\t\t\tdefs(a = false, b = false),\r\n\t\t\targs(),\r\n\t\t)\r\n\t};\r\n}\r\n\r\n// Called like...\r\ntwo!(b = true);\r\n```\r\n\r\nNow you have a function-like macro which can be used very simply.\r\n\r\n### `make_orderless`\r\n\r\n`make_orderless` is an attribute macro which simplifies the process *even more* by grabbing info already available in the function's definition.\r\n\r\n```rs\r\n#[make_orderless(defs(a = false, b = false))]\r\nfn two\u003cT\u003e(a: T, b: T) -\u003e (T, T) {\r\n\t(a, b)\r\n}\r\n\r\n// Generates the same thing as `create_orderless!`...\r\n```\r\n\r\n### `impl_orderless`\r\n\r\nThe main problem with `make_orderless` is that since it generates a `macro_rules!` *right there*, it can't be used inside of `impl` blocks.\r\n\r\n```rs\r\nstruct Args {}\r\n\r\nimpl Args {\r\n\t#[make_orderless(defs(a = false, b = false))] // ERROR!!\r\n\tpub fn two(a: bool, b: bool) -\u003e (bool, bool) {\r\n\t\t(a, b)\r\n\t}\r\n}\r\n```\r\n\r\nFortunately, the `impl_orderless` macro makes this possible.\r\n\r\n```rs\r\nstruct Args {}\r\n\r\n#[impl_orderless]\r\nimpl Args {\r\n\t#[make_orderless(defs(a = false, b = false))] // SUCCESS!!\r\n\tpub fn two(a: bool, b: bool) -\u003e (bool, bool) {\r\n\t\t(a, b)\r\n\t}\r\n}\r\n```\r\n\r\nIt does this by removing all the `make_orderless` attributes and converting them into `create_orderless!` outside of the `impl` block.\r\n\r\nWith all this chaining it's macro-ception. A macro that converts a macro to another macro, which creates a macro, which calls a macro. But in the end this is all compile-time and doesn't impact runtime performance at all. `two!()` simply compiles to `two(false, false)`!\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyza%2Forderless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkyza%2Forderless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyza%2Forderless/lists"}