Skip to content

Commit

Permalink
fixup! Feature: stable header generation This makes the generated hea…
Browse files Browse the repository at this point in the history
…der feature fixed-order iteration over the `#[ffi_export]`-ed functions (sorted by name), to palliate the lack of order-of-iteration guarantees from the internal `inventory` crate.
  • Loading branch information
danielhenrymantilla committed Oct 14, 2021
1 parent 34b7dee commit 6f6b8a2
Showing 1 changed file with 33 additions and 14 deletions.
47 changes: 33 additions & 14 deletions src/headers/_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@ with_optional_fields! {
///
/// It defaults to [`Language::C`].
language: Language,

/// Whether to yield a stable header or not (order of defined items guaranteed
/// not to change provided the source code doesn't change either).
///
/// It defaults to `true`.
stable_header: bool,
}

impl Builder<'_, WhereTo> {
Expand Down Expand Up @@ -394,20 +400,33 @@ impl Builder<'_, WhereTo> {
)?,
}
/* User-provided defs! */
// Sort the definitions for a reliable header generation.
let sorted_definitions =
crate::inventory::iter
.into_iter()
.map(|crate::FfiExport { name, gen_def }| (name, gen_def))
.collect::<::std::collections::BTreeMap<_, _>>()
;
sorted_definitions
.values()
// Iterate in reverse fashion to more closely match
// the Rust definition order.
.try_for_each(|gen_def| gen_def(&mut definer, lang))
?
;
let stable_header = config.stable_header.unwrap_or(true);
let (mut storage0, mut storage1) = (None, None);
let gen_defs: &mut dyn Iterator<Item = _> = if stable_header {
// Sort the definitions for a reliable header generation.
let sorted_definitions =
crate::inventory::iter
.into_iter()
.map(|crate::FfiExport { name, gen_def }| (name, gen_def))
.collect::<::std::collections::BTreeMap<_, _>>()
;
storage0.get_or_insert(
sorted_definitions
.into_iter()
.map(|(_, gen_def)| gen_def)
)
} else {
storage1.get_or_insert(
crate::inventory::iter
.into_iter()
// Iterate in reverse fashion to more closely match
// the Rust definition order.
.collect::<rust::Vec<_>>().into_iter().rev()
.map(|crate::FfiExport { gen_def, .. }| gen_def)
)
};
(&mut { gen_defs }).try_for_each(|gen_def| gen_def(&mut definer, lang))?;

// Epilogue
match lang {
| Language::C => write!(definer.out(),
Expand Down

0 comments on commit 6f6b8a2

Please sign in to comment.