use toasty_core::schema::app::{self, ModelId, ModelSet};
pub fn generate_unique_id() -> ModelId {
use std::sync::atomic::{AtomicUsize, Ordering};
static NEXT_MODEL_ID: AtomicUsize = AtomicUsize::new(0);
let id = NEXT_MODEL_ID.fetch_add(1, Ordering::Relaxed);
ModelId(id)
}
pub trait Register {
fn id() -> ModelId;
fn schema() -> app::Model;
fn register(model_set: &mut ModelSet);
}
#[doc(hidden)]
pub struct DiscoverItem {
crate_name: &'static str,
add_fn: fn(&mut ModelSet),
}
impl DiscoverItem {
pub const fn new(crate_name: &'static str, add_fn: fn(&mut ModelSet)) -> Self {
Self { crate_name, add_fn }
}
pub fn crate_name(&self) -> &'static str {
self.crate_name
}
pub fn add_to(&self, model_set: &mut ModelSet) {
(self.add_fn)(model_set)
}
pub fn add_all_from_crate_to(model_set: &mut ModelSet, crate_name: &str) {
let crate_name = crate_name.replace("-", "_");
for item in inventory::iter::<Self> {
if item.crate_name().replace("-", "_") == crate_name {
item.add_to(model_set);
}
}
}
}
inventory::collect!(DiscoverItem);
pub use inventory;
#[allow(clippy::crate_in_macro_def)]
#[macro_export]
macro_rules! models {
(@internal $set:ident crate::* $(,$($rest:tt)*)?) => {{
::toasty::codegen_support::DiscoverItem::add_all_from_crate_to(&mut $set, env!("CARGO_PKG_NAME"));
$(
$crate::models!(@internal $set $($rest)*);
)?
}};
(@internal $set:ident $crate_name:ident::* $(,$($rest:tt)*)?) => {{
{ use ::$crate_name; }
::toasty::codegen_support::DiscoverItem::add_all_from_crate_to(&mut $set, stringify!($crate_name));
$(
$crate::models!(@internal $set $($rest)*);
)?
}};
(@internal $set:ident $model:ty $(,$($rest:tt)*)?) => {{
<$model as ::toasty::schema::Register>::register(&mut $set);
$(
$crate::models!(@internal $set $($rest)*);
)?
}};
(@internal $set:ident) => {};
($($tokens:tt)*) => {{
let mut model_set = ::toasty::schema::ModelSet::new();
$crate::models!(@internal model_set $($tokens)*);
model_set
}};
}