{"id":13611768,"url":"https://github.com/zdimension/embed-c","last_synced_at":"2025-08-21T01:32:07.281Z","repository":{"id":97140594,"uuid":"463231147","full_name":"zdimension/embed-c","owner":"zdimension","description":"Embed C code at compile time inside Rust using C2Rust","archived":false,"fork":false,"pushed_at":"2022-02-25T09:28:47.000Z","size":58,"stargazers_count":215,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-08T01:41:51.554Z","etag":null,"topics":["c","c2rust","embed","rust"],"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/zdimension.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-02-24T17:02:55.000Z","updated_at":"2025-02-12T06:39:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"66534d01-9362-451d-a3b0-bd63d05a4ada","html_url":"https://github.com/zdimension/embed-c","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zdimension/embed-c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zdimension%2Fembed-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zdimension%2Fembed-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zdimension%2Fembed-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zdimension%2Fembed-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zdimension","download_url":"https://codeload.github.com/zdimension/embed-c/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zdimension%2Fembed-c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271415019,"owners_count":24755628,"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","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["c","c2rust","embed","rust"],"created_at":"2024-08-01T19:02:05.870Z","updated_at":"2025-08-21T01:32:07.023Z","avatar_url":"https://github.com/zdimension.png","language":"Rust","readme":"# embed-c\r\n\r\n`embed-c` is a crate that allows you to embed C code inside Rust code files. The C code is\r\ntranslated into Rust code at compile time using [C2Rust](https://github.com/immunant/c2rust),\r\nwhich means that it is fully interoperable with Rust. C code can call Rust code, and vice-versa.\r\n\r\n## Basic usage\r\n```rust\r\n#![feature(rustc_private)] \r\n\r\nuse embed_c::embed_c;\r\n\r\nembed_c! {\r\n    int add(int x, int y) {\r\n        return x + y;\r\n    }\r\n}\r\n\r\nfn main() {\r\n    let x = unsafe { add(1, 2) };\r\n    println!(\"{}\", x);\r\n}\r\n```\r\n\r\n## Install\r\nThe library is not yet on crates.io. Clone the repository somewhere and set it up:\r\n```shell\r\ngit clone https://github.com/zdimension/embed-c.git\r\ncd embed-c\r\ngit submodule update --init c2rust\r\ncp Cargo.lock ..\r\ncd ..\r\n```\r\nand add this to your `Cargo.toml`:\r\n```toml\r\n[dependencies]\r\nembed-c = { path = \"./embed-c\", version = \"0.1\" }\r\n\r\n[patch.crates-io]\r\nc2rust-transpile = { path = \"./embed-c/c2rust/c2rust-transpile\" }\r\n```\r\n\r\n**NOTE:** this crate is designed to work for the `nightly-2019-12-05` version of Rust, \r\nso put this in your `rust-toolchain.toml`:\r\n```toml\r\n[toolchain]\r\nchannel = \"nightly-2019-12-05\"\r\n```\r\nAnd change the `package.edition` setting in your `Cargo.toml` to be \"2018\":\r\n```toml\r\n[package]\r\nedition = \"2018\"\r\n```\r\n\r\nIf you get errors about the `matches!` macro, or from the `half` or `rustc_demangle` crates, copy the `Cargo.lock`\r\nfile to your project root again.\r\n\r\n## Usage details\r\n\r\nThe example at the top is translated into:\r\n```rust\r\n#[no_mangle]\r\npub unsafe extern \"C\" fn add(mut x: libc::c_int, mut y: libc::c_int)\r\n -\u003e libc::c_int {\r\n    return x + y;\r\n}\r\n\r\nfn main() {\r\n    let x = unsafe { add(1, 2) };\r\n    println!(\"{}\", x);\r\n}\r\n```\r\n\r\nThe `#![feature(rustc_private)]` bit is required since the crate uses internal features while not being loaded \r\nfrom crates.io.\r\n\r\nSee more examples in [src/lib.rs](src/lib.rs).\r\n\r\n```rust\r\nembed_c! {\r\n    void send(to, from, count)\r\n        register short *to, *from;\r\n        register count;\r\n    {\r\n        register n = (count + 7) / 8;\r\n        switch (count % 8) {\r\n        case 0: do { *to++ = *from++;\r\n        case 7:      *to++ = *from++;\r\n        case 6:      *to++ = *from++;\r\n        case 5:      *to++ = *from++;\r\n        case 4:      *to++ = *from++;\r\n        case 3:      *to++ = *from++;\r\n        case 2:      *to++ = *from++;\r\n        case 1:      *to++ = *from++;\r\n                } while (--n \u003e 0);\r\n        }\r\n    }\r\n}\r\n\r\nfn main() {\r\n    let mut source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\r\n    let mut dest = [0; 10];\r\n    unsafe { send(dest.as_mut_ptr(), source.as_mut_ptr(), 10); };\r\n    assert_eq!(source, dest);\r\n}\r\n```\r\n\r\nHere, the `send` function becomes:\r\n```rust\r\n#[no_mangle]\r\npub unsafe extern \"C\" fn send(mut to: *mut libc::c_short,\r\n                              mut from: *mut libc::c_short,\r\n                              mut count: libc::c_int) {\r\n    let mut n: libc::c_int = (count + 7 as libc::c_int) / 8 as libc::c_int;\r\n    let mut current_block_7: u64;\r\n    match count % 8 as libc::c_int {\r\n        0 =\u003e { current_block_7 = 8258075665625361029; }\r\n        7 =\u003e { current_block_7 = 8412423308551259261; }\r\n        6 =\u003e { current_block_7 = 15077176690991321518; }\r\n        ...\r\n        1 =\u003e { current_block_7 = 14053040055230693409; }\r\n        _ =\u003e { current_block_7 = 13586036798005543211; }\r\n    }\r\n    loop  {\r\n        match current_block_7 {\r\n            13586036798005543211 =\u003e { return; }\r\n            8258075665625361029 =\u003e {\r\n                let fresh0 = from;\r\n                from = from.offset(1);\r\n                let fresh1 = to;\r\n                to = to.offset(1);\r\n                *fresh1 = *fresh0;\r\n                current_block_7 = 8412423308551259261;\r\n            }\r\n            8412423308551259261 =\u003e ...\r\n            ...\r\n            _ =\u003e {\r\n                let fresh14 = from;\r\n                from = from.offset(1);\r\n                let fresh15 = to;\r\n                to = to.offset(1);\r\n                *fresh15 = *fresh14;\r\n                n -= 1;\r\n                if n \u003e 0 as libc::c_int {\r\n                    current_block_7 = 8258075665625361029;\r\n                } else { current_block_7 = 13586036798005543211; }\r\n            }\r\n        }\r\n    };\r\n}\r\n```\r\nAs you can see, the interweaved switch-do construct is transpiled into a very idiomatic Rust function through the use of pattern matching. You may not like it, but this is what peak functional programming looks like.\r\n\r\n## Limitations\r\nMany\r\n\r\n## Motivation\r\nN/A\r\n\r\n## License\r\nThis project is licensed under either of\r\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\r\n  https://www.apache.org/licenses/LICENSE-2.0)\r\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or\r\n  https://opensource.org/licenses/MIT)\r\n  at your option.\r\n","funding_links":[],"categories":["Rust","FFI Bindings"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzdimension%2Fembed-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzdimension%2Fembed-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzdimension%2Fembed-c/lists"}