LibUnicode: Generate FFI bindings with cbindgen

This places the exported structs and functions in the Unicode::FFI
namespace.
This commit is contained in:
Andrew Kaster
2026-03-17 18:03:57 -06:00
committed by Tim Flynn
parent b4185f0ecd
commit 6b1a346fad
Notes: github-actions[bot] 2026-03-18 12:37:29 +00:00
6 changed files with 64 additions and 50 deletions

1
Cargo.lock generated
View File

@@ -383,6 +383,7 @@ name = "libunicode_rust"
version = "0.1.0"
dependencies = [
"calendrical_calculations",
"cbindgen",
"icu_calendar",
]

View File

@@ -5,47 +5,7 @@
*/
#include <LibUnicode/Calendar.h>
struct FfiISODate {
i32 year;
u8 month;
u8 day;
};
struct FfiOptionalISODate {
FfiISODate iso_date;
bool has_value;
};
struct FfiCalendarDate {
i32 year;
u8 month;
u8 month_code[5];
u8 month_code_length;
u8 day;
u8 day_of_week;
u16 day_of_year;
u8 days_in_week;
u8 days_in_month;
u16 days_in_year;
u8 months_in_year;
bool in_leap_year;
};
extern "C" {
FfiCalendarDate icu_iso_date_to_calendar_date(u8 const* calendar, size_t calendar_length, i32 iso_year, u8 iso_month, u8 iso_day);
FfiOptionalISODate icu_calendar_date_to_iso_date(u8 const* calendar, size_t calendar_length, i32 arithmetic_year, u8 ordinal_month, u8 day);
FfiOptionalISODate icu_iso_year_and_month_code_to_iso_date(u8 const* calendar, size_t calendar_length, i32 iso_year, u8 const* month_code, size_t month_code_length, u8 day);
FfiOptionalISODate icu_calendar_year_and_month_code_to_iso_date(u8 const* calendar, size_t calendar_length, i32 arithmetic_year, u8 const* month_code, size_t month_code_length, u8 day);
u8 icu_calendar_months_in_year(u8 const* calendar, size_t calendar_length, i32 arithmetic_year);
u8 icu_calendar_days_in_month(u8 const* calendar, size_t calendar_length, i32 arithmetic_year, u8 ordinal_month);
u8 icu_calendar_max_days_in_month_code(u8 const* calendar, size_t calendar_length, u8 const* month_code, size_t month_code_length);
bool icu_year_contains_month_code(u8 const* calendar, size_t calendar_length, i32 arithmetic_year, u8 const* month_code, size_t month_code_length);
} // extern "C"
#include <LibUnicode/RustFFI.h>
namespace Unicode {
@@ -126,7 +86,7 @@ String create_month_code(u8 month_number, bool is_leap_month)
CalendarDate iso_date_to_calendar_date(String const& calendar, ISODate iso_date)
{
auto result = icu_iso_date_to_calendar_date(calendar.bytes().data(), calendar.bytes().size(), iso_date.year, iso_date.month, iso_date.day);
auto result = FFI::icu_iso_date_to_calendar_date(calendar.bytes().data(), calendar.bytes().size(), iso_date.year, iso_date.month, iso_date.day);
return CalendarDate {
.era = {},
@@ -148,7 +108,7 @@ CalendarDate iso_date_to_calendar_date(String const& calendar, ISODate iso_date)
Optional<ISODate> calendar_date_to_iso_date(String const& calendar, i32 year, u8 month, u8 day)
{
auto result = icu_calendar_date_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), year, month, day);
auto result = FFI::icu_calendar_date_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), year, month, day);
if (!result.has_value)
return {};
@@ -157,7 +117,7 @@ Optional<ISODate> calendar_date_to_iso_date(String const& calendar, i32 year, u8
Optional<ISODate> iso_year_and_month_code_to_iso_date(String const& calendar, i32 year, StringView month_code, u8 day)
{
auto result = icu_iso_year_and_month_code_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), year, month_code.bytes().data(), month_code.length(), day);
auto result = FFI::icu_iso_year_and_month_code_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), year, month_code.bytes().data(), month_code.length(), day);
if (!result.has_value)
return {};
@@ -166,7 +126,7 @@ Optional<ISODate> iso_year_and_month_code_to_iso_date(String const& calendar, i3
Optional<ISODate> calendar_year_and_month_code_to_iso_date(String const& calendar, i32 arithmetic_year, StringView month_code, u8 day)
{
auto result = icu_calendar_year_and_month_code_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, month_code.bytes().data(), month_code.length(), day);
auto result = FFI::icu_calendar_year_and_month_code_to_iso_date(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, month_code.bytes().data(), month_code.length(), day);
if (!result.has_value)
return {};
@@ -175,22 +135,22 @@ Optional<ISODate> calendar_year_and_month_code_to_iso_date(String const& calenda
u8 calendar_months_in_year(String const& calendar, i32 arithmetic_year)
{
return icu_calendar_months_in_year(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year);
return FFI::icu_calendar_months_in_year(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year);
}
u8 calendar_days_in_month(String const& calendar, i32 arithmetic_year, u8 ordinal_month)
{
return icu_calendar_days_in_month(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, ordinal_month);
return FFI::icu_calendar_days_in_month(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, ordinal_month);
}
u8 calendar_max_days_in_month_code(String const& calendar, StringView month_code)
{
return icu_calendar_max_days_in_month_code(calendar.bytes().data(), calendar.bytes().size(), month_code.bytes().data(), month_code.length());
return FFI::icu_calendar_max_days_in_month_code(calendar.bytes().data(), calendar.bytes().size(), month_code.bytes().data(), month_code.length());
}
bool calendar_year_contains_month_code(String const& calendar, i32 arithmetic_year, StringView month_code)
{
return icu_year_contains_month_code(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, month_code.bytes().data(), month_code.length());
return FFI::icu_year_contains_month_code(calendar.bytes().data(), calendar.bytes().size(), arithmetic_year, month_code.bytes().data(), month_code.length());
}
}

View File

@@ -11,3 +11,6 @@ crate-type = ["staticlib"]
[dependencies]
calendrical_calculations = "0.2"
icu_calendar = { version = "2.1.1", features = ["compiled_data"] }
[build-dependencies]
cbindgen = "0.29"

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2026-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
use std::env;
use std::error::Error;
use std::path::PathBuf;
fn main() -> Result<(), Box<dyn Error>> {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=cbindgen.toml");
let ffi_out_dir = env::var("FFI_OUTPUT_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| out_dir.clone());
cbindgen::generate(manifest_dir).map_or_else(
|error| match error {
cbindgen::Error::ParseSyntaxError { .. } => {}
e => panic!("{e:?}"),
},
|bindings| {
bindings.write_to_file(ffi_out_dir.join("RustFFI.h"));
},
);
Ok(())
}

View File

@@ -0,0 +1,17 @@
language = "C++"
header = """/*
* Copyright (c) 2026-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/"""
pragma_once = true
include_version = true
namespaces = ["Unicode", "FFI"]
line_length = 120
tab_width = 4
no_includes = true
sys_includes = ["stdint.h", "stddef.h"]
usize_is_size_t = true
[export.mangle]
rename_types = "PascalCase"

View File

@@ -4,4 +4,4 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
mod calendar;
pub mod calendar;