sdecay/sys/tests.rs
2025-07-03 13:09:36 +03:00

221 lines
6.4 KiB
Rust

#![expect(unsafe_code)]
use core::{ffi::CStr, mem::MaybeUninit};
use crate::sandia_decay::{Ci, year};
macro_rules! string {
($name:ident = $cstr:expr) => {
let mut $name = MaybeUninit::uninit();
crate::sdecay::std_string_from_cstr($name.as_mut_ptr(), $cstr.as_ptr());
let $name = $name.as_mut_ptr();
};
}
macro_rules! string_drop {
($name:ident) => {
crate::sdecay::std_string_destruct($name);
};
}
#[test]
fn create_std_string() {
unsafe {
string!(s = c"abc42");
assert!(CStr::from_ptr(crate::sdecay::std_string_cstr(s.cast_const())) == c"abc42");
string_drop!(s);
}
}
macro_rules! database {
($name:ident) => {
let mut $name = MaybeUninit::uninit();
crate::sandia_decay::SandiaDecayDataBase_SandiaDecayDataBase1($name.as_mut_ptr());
string!(path = c"vendor/sandia.decay.xml");
crate::sandia_decay::SandiaDecayDataBase_initialize($name.as_mut_ptr(), path);
string_drop!(path);
let $name = $name.as_mut_ptr();
};
}
macro_rules! database_drop {
($name:ident) => {
crate::sandia_decay::SandiaDecayDataBase_SandiaDecayDataBase_destructor($name);
};
}
#[test]
fn create_database() {
unsafe {
// create and initialize database
database!(db);
// drop the database
database_drop!(db);
}
}
#[test]
fn get_nuclide() {
unsafe {
database!(db);
string!(nuc = c"U-238");
let nuclide = &*crate::sandia_decay::SandiaDecayDataBase_nuclide(db, nuc);
string_drop!(nuc);
let symbol = &nuclide.symbol;
let symbol = crate::sdecay::std_string_cstr(core::ptr::from_ref(symbol));
assert!(CStr::from_ptr(symbol) == c"U238");
database_drop!(db);
}
}
macro_rules! mixture {
($name:ident) => {
let mut $name = MaybeUninit::uninit();
crate::sandia_decay::NuclideMixture_NuclideMixture($name.as_mut_ptr());
let $name = $name.as_mut_ptr();
};
}
macro_rules! mixture_drop {
($name:ident) => {
crate::sandia_decay::NuclideMixture_NuclideMixture_destructor($name);
};
}
#[test]
fn create_mixture() {
unsafe {
// create empty mixture
mixture!(mx);
// drop mixture
mixture_drop!(mx);
}
}
#[test]
fn populate_mixture() {
unsafe {
mixture!(mx);
database!(db);
string!(nuc = c"U-238");
let nuclide = &*crate::sandia_decay::SandiaDecayDataBase_nuclide(db, nuc);
string_drop!(nuc);
crate::sandia_decay::NuclideMixture_addNuclideByActivity(mx, nuclide, 1e-3 * Ci);
database_drop!(db);
mixture_drop!(mx);
}
}
#[test]
fn solve_mixture() {
unsafe {
mixture!(mx);
database!(db);
string!(nuc = c"U-238");
let nuclide = &*crate::sandia_decay::SandiaDecayDataBase_nuclide(db, nuc);
string_drop!(nuc);
crate::sandia_decay::NuclideMixture_addNuclideByActivity(mx, nuclide, 1e-3 * Ci);
let _activity_20y =
crate::sandia_decay::NuclideMixture_totalActivity(mx.cast_const(), 20.0 * year);
database_drop!(db);
mixture_drop!(mx);
}
}
#[test]
fn perform_evolution() {
unsafe {
mixture!(mx);
database!(db);
string!(nuc = c"U-238");
let nuclide = &*crate::sandia_decay::SandiaDecayDataBase_nuclide(db, nuc);
string_drop!(nuc);
crate::sandia_decay::NuclideMixture_addNuclideByActivity(mx, nuclide, 1e-3 * Ci);
let _evolution =
crate::sandia_decay::NuclideMixture_decayedToNuclidesEvolutions(mx.cast_const());
database_drop!(db);
mixture_drop!(mx);
}
}
mod layout {
macro_rules! layout {
($name:ident, $type:ty) => {
mod $name {
#[test]
fn size() {
let rust_size = core::mem::size_of::<$type>();
let c_size = unsafe { crate::sdecay::layout::$name::size };
assert_eq!(rust_size, c_size, "Binding type should have correct size");
}
#[test]
fn align() {
let rust_align = core::mem::align_of::<$type>();
let c_align = unsafe { crate::sdecay::layout::$name::align };
assert_eq!(
rust_align, c_align,
"Binding type should have correct alignment"
);
}
}
};
}
layout!(std_string, crate::sdecay::string);
layout!(database, crate::sandia_decay::SandiaDecayDataBase);
layout!(mixture, crate::sandia_decay::NuclideMixture);
layout!(nuclide, crate::sandia_decay::Nuclide);
layout!(transition, crate::sandia_decay::Transition);
layout!(rad_particle, crate::sandia_decay::RadParticle);
layout!(
nuclide_abundance_pair,
crate::sandia_decay::NuclideAbundancePair
);
layout!(
nuclide_activity_pair,
crate::sandia_decay::NuclideActivityPair
);
layout!(
nuclide_num_atoms_pair,
crate::sandia_decay::NuclideNumAtomsPair
);
layout!(
energy_intensity_pair,
crate::sandia_decay::EnergyIntensityPair
);
layout!(energy_count_pair, crate::sandia_decay::EnergyCountPair);
layout!(energy_rate_pair, crate::sandia_decay::EnergyRatePair);
layout!(element, crate::sandia_decay::Element);
layout!(time_evolution_term, crate::sandia_decay::TimeEvolutionTerm);
layout!(
nuclide_time_evolution,
crate::sandia_decay::NuclideTimeEvolution
);
macro_rules! layout_sdecay {
($name:ident) => {
layout!($name, crate::sdecay::$name);
};
}
layout_sdecay!(char_vec);
layout_sdecay!(transition_vec);
layout_sdecay!(transition_ptr_vec);
layout_sdecay!(rad_particle_vec);
layout_sdecay!(nuclide_abundance_pair_vec);
layout_sdecay!(nuclide_activity_pair_vec);
layout_sdecay!(nuclide_num_atoms_pair_vec);
layout_sdecay!(energy_intensity_pair_vec);
layout_sdecay!(energy_count_pair_vec);
layout_sdecay!(energy_rate_pair_vec);
layout_sdecay!(nuclide_vec);
layout_sdecay!(nuclide_ref_vec);
layout_sdecay!(nuclide_raw_ptr_vec);
layout_sdecay!(element_vec);
layout_sdecay!(element_raw_ptr_vec);
layout_sdecay!(element_ref_vec);
layout_sdecay!(coincidence_pair_vec);
layout_sdecay!(time_evolution_term_vec);
layout_sdecay!(nuclide_time_evolution_vec);
}