{"id":22246717,"url":"https://github.com/lucacappelletti94/invariant-rs","last_synced_at":"2025-03-25T11:24:56.655Z","repository":{"id":264968138,"uuid":"863381661","full_name":"LucaCappelletti94/invariant-rs","owner":"LucaCappelletti94","description":"Rust macros for invariant assertions.","archived":false,"fork":false,"pushed_at":"2024-09-28T09:52:07.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T09:51:39.595Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/LucaCappelletti94.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":"2024-09-26T07:45:05.000Z","updated_at":"2024-09-28T09:52:10.000Z","dependencies_parsed_at":"2024-11-27T02:12:04.903Z","dependency_job_id":"aaa3e75c-41a2-4046-8575-ab99c36b17ad","html_url":"https://github.com/LucaCappelletti94/invariant-rs","commit_stats":null,"previous_names":["lucacappelletti94/invariant-rs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Finvariant-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Finvariant-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Finvariant-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Finvariant-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucaCappelletti94","download_url":"https://codeload.github.com/LucaCappelletti94/invariant-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245451342,"owners_count":20617496,"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-12-03T05:30:14.554Z","updated_at":"2025-03-25T11:24:56.616Z","avatar_url":"https://github.com/LucaCappelletti94.png","language":"Rust","readme":"# Invariant-rs\nRust macros for invariant assertions, allowing for the definition of axiomatic conditions that are necessarily always true at a particular point in a program, checked in debug mode and exploited by the compiler as certainly true in release mode to optimize the code.\n\n## What is an invariant?\nAn invariant is a axiomatic condition that is always true at a particular point in a program. While we generally want to test for such conditions during debug mode, as one never knows whether the code is actually correct, we want to inform the compiler that the condition can be assumed to be true in release mode. This is where macros such as `invariant!` comes in. Take the following examples:\n\n```rust\nuse invariant_rs::invariant_ne;\n\n#[inline(never)]\npub fn my_log1(x: usize) -\u003e u32 {\n    debug_assert_ne!(x, 0);\n    x.ilog2()\n}\n\n#[inline(never)]\npub fn my_log2(x: usize) -\u003e u32 {\n    invariant_ne!(x, 0);\n    x.ilog2()\n}\n```\n\nThe first method, `my_log1`, will be compiled in relase as:\n\n```assembly\nmy_log1:\n    test    rdi, rdi\n    je      .LBB0_2\n    bsr     rax, rdi\n    ret\n.LBB0_2:\n    push    rax\n    lea     rdi, [rip + .L__unnamed_1]\n    call    qword ptr [rip + panic_for_nonpositive_argument]\n```\n\nWhile the second method, `my_log2`, will be compiled to the much simpler:\n\n```assembly\nmy_log2:\n    bsr     rax, rdi\n    ret\n```\n\nThe second method is identical to:\n    \n```rust\n#[inline(never)]\npub fn my_log2(x: usize) -\u003e u32 {\n    debug_assert_ne!(x, 0);\n    if x == 0 {\n        unsafe {\n            core::hint::unreachable_unchecked();\n        }\n    }\n    x.ilog2()\n}\n```\n\nNote that the compile directive `#[inline(never)]` is used to prevent the compiler from inlining the method, which would make the assembly code harder to read. The `invariant_ne!` macro is used to inform the compiler that the condition `x != 0` is always true, and thus the compiler can optimize the code accordingly.\n\n## Usage\n\nYou can use the `invariant!` macro to add assertions to your code:\n\n```rust\nuse invariant_rs::invariant;\n\nlet x = 0;\ninvariant!(x == 0);\n```\n\nSimilarly, the crate offers the `invariant_eq!` macro to check for equality:\n\n```rust\nuse invariant_rs::invariant_eq;\n\nlet x = 0;\ninvariant_eq!(x, 0);\n```\n\nAnd the `invariant_ne!` macro to check for inequality:\n\n```rust\nuse invariant_rs::invariant_ne;\n\nlet x = 0;\ninvariant_ne!(x, 1);\n```\n\nAnd the `invariant_lt!` macro to check for less than:\n\n```rust\nuse invariant_rs::invariant_lt;\n\nlet x = 0;\ninvariant_lt!(x, 1);\n```\n\nAnd the `invariant_le!` macro to check for less than or equal:\n\n```rust\nuse invariant_rs::invariant_le;\n\nlet x = 0;\ninvariant_le!(x, 0);\n```\n\nAnd the `invariant_gt!` macro to check for greater than:\n\n```rust\nuse invariant_rs::invariant_gt;\n\nlet x = 1;\ninvariant_gt!(x, 0);\n```\n\nAnd the `invariant_ge!` macro to check for greater than or equal:\n\n```rust\nuse invariant_rs::invariant_ge;\n\nlet x = 0;\ninvariant_ge!(x, 0);\n```\n\n## What happens if unchecked unreacheable code is reached?\nIf the `debug_assertions` are enabled, the program will panic. If the `debug_assertions` are disabled, the compiler may place a [`ud2` instruction](https://en.wikipedia.org/wiki/Illegal_opcode), a type of illegal instruction, which will cause the program to crash. In some other cases, the code may not have any apparent effect, **which is why you should use test the condition thoroughly in debug mode!**\n\n### Example generating a `ud2` instruction in release mode\nIf you try to compile the following code in release mode, the compiler will generate a `ud2` instruction, which will cause the program to crash.\n\n```no_run\nuse invariant_rs::invariant;\n\nlet x = 0;\ninvariant!(x == 1);\n```\n\nThe assembly code it generates is simply:\n\n```x86asm\nmain:\n    ud2\n```\n\n## No STD\nThis crate is `no_std` compatible, and can be used in embedded systems.\n\n## Contributing\nWould you like to add some more assertions to this collection? Open up an issue and let's discuss it!\n\n## License\nThis crate is released under the MIT license. You can find the complete text in the [`LICENSE`](https://github.com/LucaCappelletti94/invariant-rs/blob/main/LICENSE) file.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Finvariant-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucacappelletti94%2Finvariant-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Finvariant-rs/lists"}