ffi-enum

Crates.ioffi-enum
lib.rsffi-enum
version
sourcesrc
created_at2025-02-13 13:12:52.150562+00
updated_at2025-02-24 09:28:32.576108+00
descriptionSimply write and use `enum`s like rust native enums, freely passing through ffi
homepagehttps://github.com/AlseinX/ffi-enum
repositoryhttps://github.com/AlseinX/ffi-enum
max_upload_size
id1554193
Cargo.toml error:TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Alsein (AlseinX)

documentation

https://docs.rs/ffi-enum

README

ffi-enum

Simply write and use enums like rust native enums, freely passing through ffi.

Crates.io Docs.rs MIT Or Apache-2.0 licensed Build Status

Why not using #[repr(C)] and #[non_exhaustive] ?

  • Rust's #[repr(C)] is not fully equal to a C-abi enum, and it is still an undefined behavior when an enum defined with #[repr(C)] recieves a value that is not listed in the definition of enum, from ffi.
  • #[non_exhaustive] is only designed for inter-crate compatibility, while the compiler might still optimize based on the assumption that the binary pattern of an enum value is always in its defined range.

Why not existing alternatives?

The current alternatives mostly define complex DSL with function macros, which could be hard to read/maintain and not supported by rustfmt or rust-analyzer, and they do not support derive macros.

While this crate offers a nearly native experience by trying the best to fully mimic the behaviors of native enums, despite it requires non-exhaustive matching even inside the defining crate. FFi enums are defined with native rust enum item syntax with full support of formatting, code hint, and auto completion.

use ffi_enum::prelude::*;
use serde::{Deserialize, Serialize};

#[ffi_enum]
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Animal {
    Cat,
    Dog,
}

fn main() {
    let json = serde_json::to_string(&Animal::Cat).unwrap();
    assert_eq!(json, "\"cat\"");
    let value: Animal = serde_json::from_str(&json).unwrap();
    assert_eq!(value, Animal::Cat);
    let json = serde_json::to_string(&Animal::from(100u8)).unwrap();
    assert_eq!(json, "\"<Unknown>\"");
    let value: Animal = serde_json::from_str(&json).unwrap();
    assert_eq!(value, Animal::UNKNOWN);
}
Commit count: 7

cargo fmt