use std::{
path::PathBuf,
sync::atomic::{AtomicUsize, Ordering},
};
use prebindgen_registry::{Registry, RegistryBuilder};
pub(crate) fn reg_from_items<M, I>(
items: I,
) -> Result<RegistryBuilder<M>, prebindgen_registry::ScanError>
where
I: IntoIterator<Item = (syn::Item, prebindgen::SourceLocation)>,
{
let flat = prebindgen_registry::Flat::builder().items(items).build()?;
Registry::builder(flat)
}
pub(crate) fn declare_referenced<I>(items: I) -> Vec<(syn::Item, prebindgen::SourceLocation)>
where
I: IntoIterator<Item = (syn::Item, prebindgen::SourceLocation)>,
{
use prebindgen_registry::flat::{Flat, ItemError};
let mut items: Vec<(syn::Item, prebindgen::SourceLocation)> = items.into_iter().collect();
loop {
let flat = Flat::builder()
.items(items.iter().cloned())
.build()
.expect("fixture parses");
let missing: std::collections::BTreeSet<String> = flat
.unsupported()
.filter_map(|u| match &*u.error {
ItemError::UnresolvedType { name }
if !name.contains("::") && flat.element(name).is_none() =>
{
Some(name.clone())
}
_ => None,
})
.collect();
if missing.is_empty() {
return items;
}
for name in missing {
let ident = quote::format_ident!("{name}");
let alias: syn::Item = syn::parse_quote!(
pub type #ident = __fixture::#ident;
);
items.push((alias, prebindgen::SourceLocation::default()));
}
}
}
pub(crate) fn unique_test_dir(prefix: &str) -> PathBuf {
static SEQ: AtomicUsize = AtomicUsize::new(0);
let seq = SEQ.fetch_add(1, Ordering::Relaxed);
std::env::temp_dir().join(format!("{prefix}_{}_{}", std::process::id(), seq))
}