{"id":14992005,"url":"https://github.com/HKalbasi/zngur","last_synced_at":"2025-09-25T14:30:38.656Z","repository":{"id":186211349,"uuid":"674376414","full_name":"HKalbasi/zngur","owner":"HKalbasi","description":"A C++/Rust interop tool","archived":false,"fork":false,"pushed_at":"2025-01-10T17:01:28.000Z","size":1683,"stargazers_count":251,"open_issues_count":5,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-01-10T20:11:25.451Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hkalbasi.github.io/zngur","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HKalbasi.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-03T19:49:40.000Z","updated_at":"2025-01-10T17:01:31.000Z","dependencies_parsed_at":"2024-12-13T16:09:23.440Z","dependency_job_id":"6772e1ab-4b13-4d04-aae6-a146d27c5070","html_url":"https://github.com/HKalbasi/zngur","commit_stats":null,"previous_names":["hkalbasi/zngur"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fzngur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fzngur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fzngur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HKalbasi%2Fzngur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HKalbasi","download_url":"https://codeload.github.com/HKalbasi/zngur/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234200156,"owners_count":18795139,"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-09-24T15:00:38.954Z","updated_at":"2025-09-25T14:30:38.650Z","avatar_url":"https://github.com/HKalbasi.png","language":"Rust","funding_links":[],"categories":["FFI Bindings"],"sub_categories":[],"readme":"# Zngur\n\n[\u003cimg alt=\"github\" src=\"https://img.shields.io/badge/github-hkalbasi/zngur-8da0cb?style=for-the-badge\u0026labelColor=555555\u0026logo=github\" height=\"20\"\u003e](https://github.com/hkalbasi/zngur)\n[\u003cimg alt=\"crates.io\" src=\"https://img.shields.io/crates/v/zngur.svg?style=for-the-badge\u0026color=fc8d62\u0026logo=rust\" height=\"20\"\u003e](https://crates.io/crates/zngur)\n[\u003cimg alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-zngur-66c2a5?style=for-the-badge\u0026labelColor=555555\u0026logo=docs.rs\" height=\"20\"\u003e](https://docs.rs/zngur)\n[\u003cimg alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/hkalbasi/zngur/ci.yml?branch=main\u0026style=for-the-badge\" height=\"20\"\u003e](https://github.com/hkalbasi/zngur/actions?query=branch%3Amain)\n\nZngur (/zængɑr/) is a C++/Rust interop tool. It tries to expose arbitrary Rust types, methods and functions, while preserving its\nsemantics and ergonomics as much as possible. Using Zngur, you can use arbitrary Rust crates in your C++ code as easily as using it in\nnormal Rust code, and you can write idiomatic Rusty APIs for your C++ library inside C++. See [the documentation](https://hkalbasi.github.io/zngur/)\nfor more info.\n\n## Demo\n\n```C++\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n\n#include \"./generated.h\"\n\n// Rust values are available in the `::rust` namespace from their absolute path\n// in Rust\ntemplate \u003ctypename T\u003e using Vec = rust::std::vec::Vec\u003cT\u003e;\ntemplate \u003ctypename T\u003e using Option = rust::std::option::Option\u003cT\u003e;\ntemplate \u003ctypename T\u003e using BoxDyn = rust::Box\u003crust::Dyn\u003cT\u003e\u003e;\n\n// You can implement Rust traits for your classes\ntemplate \u003ctypename T\u003e\nclass VectorIterator : public rust::std::iter::Iterator\u003cT\u003e {\n  std::vector\u003cT\u003e vec;\n  size_t pos;\n\npublic:\n  VectorIterator(std::vector\u003cT\u003e \u0026\u0026v) : vec(v), pos(0) {}\n  ~VectorIterator() {\n    std::cout \u003c\u003c \"vector iterator has been destructed\" \u003c\u003c std::endl;\n  }\n\n  Option\u003cT\u003e next() override {\n    if (pos \u003e= vec.size()) {\n      return Option\u003cT\u003e::None();\n    }\n    T value = vec[pos++];\n    // You can construct Rust enum with fields in C++\n    return Option\u003cT\u003e::Some(value);\n  }\n};\n\nint main() {\n  // You can call Rust functions that return things by value, and store that\n  // value in your stack.\n  auto s = Vec\u003cint32_t\u003e::new_();\n  s.push(2);\n  Vec\u003cint32_t\u003e::push(s, 5);\n  s.push(7);\n  Vec\u003cint32_t\u003e::push(s, 3);\n  // You can call Rust functions just like normal Rust.\n  std::cout \u003c\u003c s.clone().into_iter().sum() \u003c\u003c std::endl;\n  // You can catch Rust panics as C++ exceptions\n  try {\n    std::cout \u003c\u003c \"s[2] = \" \u003c\u003c *s.get(2).unwrap() \u003c\u003c std::endl;\n    std::cout \u003c\u003c \"s[4] = \" \u003c\u003c *s.get(4).unwrap() \u003c\u003c std::endl;\n  } catch (rust::Panic e) {\n    std::cout \u003c\u003c \"Rust panic happened\" \u003c\u003c std::endl;\n  }\n  int state = 0;\n  // You can convert a C++ lambda into a `Box\u003cdyn Fn\u003e` and friends.\n  auto f = BoxDyn\u003crust::Fn\u003cint32_t, int32_t\u003e\u003e::make_box([\u0026](int32_t x) {\n    state += x;\n    std::cout \u003c\u003c \"hello \" \u003c\u003c x \u003c\u003c \" \" \u003c\u003c state \u003c\u003c \"\\n\";\n    return x * 2;\n  });\n  // And pass it to Rust functions that accept closures.\n  auto x = s.into_iter().map(std::move(f)).sum();\n  std::cout \u003c\u003c x \u003c\u003c \" \" \u003c\u003c state \u003c\u003c \"\\n\";\n  std::vector\u003cint32_t\u003e vec{10, 20, 60};\n  // You can convert a C++ type that implements `Trait` to a `Box\u003cdyn Trait\u003e`.\n  // `make_box` is similar to the `make_unique`, it takes constructor arguments\n  // and construct it inside the `Box` (instead of `unique_ptr`).\n  auto vec_as_iter = BoxDyn\u003crust::std::iter::Iterator\u003cint32_t\u003e\u003e::make_box\u003c\n      VectorIterator\u003cint32_t\u003e\u003e(std::move(vec));\n  // Then use it like a normal Rust value.\n  auto t = vec_as_iter.collect();\n  // Some utilities are also provided. For example, `zngur_dbg` is the\n  // equivalent of `dbg!` macro.\n  zngur_dbg(t);\n}\n```\n\nOutput:\n\n```\n17\ns[2] = 7\nthread '\u003cunnamed\u003e' panicked at 'called `Option::unwrap()` on a `None` value', examples/simple/src/generated.rs:186:39\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\ns[4] = Rust panic happened\nhello 2 2\nhello 5 7\nhello 7 14\nhello 3 17\n34 17\nvector iterator has been destructed\n[main.cpp:71] t = [\n    10,\n    20,\n    60,\n]\n```\n\nSee the [`examples/simple`](https://github.com/HKalbasi/zngur/blob/main/examples/simple) if you want to build and run it.\n\n## Installation\n\nThe `zngur` CLI tool can be installed with cargo:\n\n```\ncargo install zngur-cli\n```\n\n\u003cbr\u003e\n\n#### License\n\n\u003csup\u003e\nLicensed under either of \u003ca href=\"LICENSE-APACHE\"\u003eApache License, Version\n2.0\u003c/a\u003e or \u003ca href=\"LICENSE-MIT\"\u003eMIT license\u003c/a\u003e at your option.\n\u003c/sup\u003e\n\n\u003cbr\u003e\n\n\u003csub\u003e\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHKalbasi%2Fzngur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHKalbasi%2Fzngur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHKalbasi%2Fzngur/lists"}