fix: warn on dropped builders and values; stop exporting EP internals

`h.event(1).team(["x"]).team(["y"]).ranking([0, 1]);` without the
terminal `.commit()` was a silent no-op: no warning, no error, and the
next thing the caller does is converge an empty history and read `None`
skills. `EventBuilder` already carried a `#[must_use]`; the value types
around it did not, so the same silence covered `Team::with_members`,
`Member::new`, `Outcome::*`, `Joint` and `Prediction::outcomes`.

`#[must_use]` now goes on the *types* rather than being sprinkled over
methods, which covers every constructor and builder setter at once and
gives the crate a rule where it previously had a list. Verified by
compiling a program that drops each one and reading the warnings back,
rather than by assuming the attribute took.

Visibility, from #73: `Gaussian::damp_natural` was reachable from
outside the crate despite being an EP damping internal called only from
`src/factor/`. The stray `pub fn`s inside the private `time_slice`,
`key_table` and `matrix` modules are now `pub(crate)`, so their
visibility states what it means instead of relying on the module being
private.

`storage/mod.rs` and `factor/mod.rs` become `storage.rs` and
`factor.rs`.

Closes #67. Refs #73.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
This commit is contained in:
2026-09-09 21:24:37 +02:00
co-authored by Claude Opus 5
parent cc601c06eb
commit e4d6dc4028
10 changed files with 29 additions and 20 deletions
+9 -6
View File
@@ -26,21 +26,24 @@ where
K: Eq + Hash + Clone,
{
#[must_use]
pub fn new() -> Self {
pub(crate) fn new() -> Self {
Self {
forward: HashMap::new(),
reverse: Vec::new(),
}
}
pub fn get<Q: ?Sized + Hash + Eq>(&self, k: &Q) -> Option<Index>
pub(crate) fn get<Q: ?Sized + Hash + Eq>(&self, k: &Q) -> Option<Index>
where
K: Borrow<Q>,
{
self.forward.get(k).cloned()
}
pub fn get_or_create<Q: ?Sized + Hash + Eq + ToOwned<Owned = K>>(&mut self, k: &Q) -> Index
pub(crate) fn get_or_create<Q: ?Sized + Hash + Eq + ToOwned<Owned = K>>(
&mut self,
k: &Q,
) -> Index
where
K: Borrow<Q>,
{
@@ -56,7 +59,7 @@ where
}
#[must_use]
pub fn key(&self, idx: Index) -> Option<&K> {
pub(crate) fn key(&self, idx: Index) -> Option<&K> {
self.reverse.get(idx.0)
}
@@ -66,12 +69,12 @@ where
/// Rust seeds its default hasher per process, so a `HashMap` walk yields a
/// different order on every run — which is fine for membership but not for
/// anything a caller might sum, sort or print.
pub fn keys(&self) -> impl ExactSizeIterator<Item = &K> {
pub(crate) fn keys(&self) -> impl ExactSizeIterator<Item = &K> {
self.reverse.iter()
}
#[must_use]
pub fn len(&self) -> usize {
pub(crate) fn len(&self) -> usize {
self.reverse.len()
}
}