#enums #derive #ffi #c-abi

ffi-enum

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

2 releases

new 0.1.2 Feb 14, 2025
0.1.1 Feb 14, 2025
0.1.0 Feb 13, 2025

#727 in Rust patterns

Download history 388/week @ 2025-02-11

388 downloads per month

MIT/Apache

12KB
88 lines

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);
}

Dependencies

~225–660KB
~15K SLoC