diff --git a/src/event.rs b/src/event.rs index b36278c..15d119f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -20,12 +20,12 @@ pub struct Event { /// A team: list of members competing together. #[derive(Clone, Debug, PartialEq)] +#[must_use] pub struct Team { pub members: SmallVec<[Member; 4]>, } impl Team { - #[must_use] pub fn new() -> Self { Self { members: SmallVec::new(), @@ -62,6 +62,7 @@ impl Default for Team { /// `InferenceError::ConflictingCompetitorConfig`: events in a batch have no /// order, so there would be no well-defined winner. #[derive(Clone, Debug, PartialEq)] +#[must_use] pub struct Member { pub key: K, pub weight: f64, diff --git a/src/factor/mod.rs b/src/factor.rs similarity index 100% rename from src/factor/mod.rs rename to src/factor.rs diff --git a/src/gaussian.rs b/src/gaussian.rs index 58a1884..a789b8f 100644 --- a/src/gaussian.rs +++ b/src/gaussian.rs @@ -243,7 +243,7 @@ impl Gaussian { /// Used by within-game inference to stabilise oscillating fixed-point /// loops on hard graphs. `alpha = 1.0` returns `new` exactly; /// `alpha < 1.0` shrinks each per-step update. - pub fn damp_natural(self, new: Gaussian, alpha: f64) -> Gaussian { + pub(crate) fn damp_natural(self, new: Gaussian, alpha: f64) -> Gaussian { Gaussian::from_natural( alpha * new.pi() + (1.0 - alpha) * self.pi(), alpha * new.tau() + (1.0 - alpha) * self.tau(), diff --git a/src/history.rs b/src/history.rs index 4d71c5f..e697d25 100644 --- a/src/history.rs +++ b/src/history.rs @@ -2630,6 +2630,7 @@ impl, O: Observer, K: Eq + Hash + Clone> std::fmt::Debug /// Slices a competitor sits out cost nothing: an absence is not an appearance, /// so a competitor seen in the first and last of a hundred slices contributes /// two variables, not a hundred. +#[must_use] pub struct Joint<'h, T: Time, D: Drift, O: Observer, K: Eq + Hash + Clone> { history: &'h History, cholesky: crate::joint::Cholesky, diff --git a/src/key_table.rs b/src/key_table.rs index b06e526..69e481c 100644 --- a/src/key_table.rs +++ b/src/key_table.rs @@ -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(&self, k: &Q) -> Option + pub(crate) fn get(&self, k: &Q) -> Option where K: Borrow, { self.forward.get(k).cloned() } - pub fn get_or_create>(&mut self, k: &Q) -> Index + pub(crate) fn get_or_create>( + &mut self, + k: &Q, + ) -> Index where K: Borrow, { @@ -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 { + pub(crate) fn keys(&self) -> impl ExactSizeIterator { self.reverse.iter() } #[must_use] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.reverse.len() } } diff --git a/src/matrix.rs b/src/matrix.rs index e9e05b3..a6d6af0 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -140,7 +140,7 @@ impl Lu { } impl Matrix { - pub fn new(height: usize, width: usize) -> Matrix { + pub(crate) fn new(height: usize, width: usize) -> Matrix { Matrix { data: vec![0.0; height * width].into_boxed_slice(), height, @@ -148,7 +148,7 @@ impl Matrix { } } - pub fn transpose(&self) -> Matrix { + pub(crate) fn transpose(&self) -> Matrix { let mut matrix = Matrix::new(self.width, self.height); for c in 0..self.width { @@ -166,7 +166,7 @@ impl Matrix { /// # Panics /// /// Panics if the matrix is not square. - pub fn determinant(&self) -> f64 { + pub(crate) fn determinant(&self) -> f64 { assert_eq!( self.width, self.height, "determinant requires a square matrix, got {}x{}", @@ -184,7 +184,7 @@ impl Matrix { /// /// See [`Lu::ln_abs_determinant`] for why a ratio of determinants must be /// taken this way. - pub fn ln_abs_determinant(&self) -> f64 { + pub(crate) fn ln_abs_determinant(&self) -> f64 { assert_eq!( self.width, self.height, "determinant requires a square matrix, got {}x{}", @@ -203,7 +203,7 @@ impl Matrix { /// # Panics /// /// Panics if the matrix is not square or is singular. - pub fn inverse(&self) -> Matrix { + pub(crate) fn inverse(&self) -> Matrix { assert_eq!( self.width, self.height, "inverse requires a square matrix, got {}x{}", diff --git a/src/outcome.rs b/src/outcome.rs index 0546b9b..d8ac3bd 100644 --- a/src/outcome.rs +++ b/src/outcome.rs @@ -16,6 +16,7 @@ use smallvec::SmallVec; /// when `Some`; `None` inherits the history default. #[derive(Clone, Debug, PartialEq)] #[non_exhaustive] +#[must_use] pub enum Outcome { Ranked(SmallVec<[u32; 4]>), #[non_exhaustive] @@ -46,7 +47,6 @@ impl Outcome { /// `p_draw > 0`. Asking "team 5 won" and silently getting "everyone drew" /// is exactly the class of quiet wrong answer this crate keeps removing, so /// the check happens here where the mistake is. - #[must_use] pub fn winner(winner: u32, n: u32) -> Self { Self::try_winner(winner, n) .unwrap_or_else(|_| panic!("winner index {winner} out of range 0..{n}")) @@ -73,7 +73,6 @@ impl Outcome { } /// All `n` teams tied. - #[must_use] pub fn draw(n: u32) -> Self { Self::Ranked(SmallVec::from_vec(vec![0; n as usize])) } diff --git a/src/predict.rs b/src/predict.rs index 081979f..8fbfa8e 100644 --- a/src/predict.rs +++ b/src/predict.rs @@ -467,6 +467,7 @@ impl Prediction { } /// Every possible finishing order and its probability, most likely first. + #[must_use] pub fn outcomes(&self) -> impl ExactSizeIterator { self.outcomes.iter().map(|(r, p)| (r.as_slice(), *p)) } diff --git a/src/storage/mod.rs b/src/storage.rs similarity index 100% rename from src/storage/mod.rs rename to src/storage.rs diff --git a/src/time_slice.rs b/src/time_slice.rs index 4ffd6a2..844fbc4 100644 --- a/src/time_slice.rs +++ b/src/time_slice.rs @@ -228,7 +228,7 @@ pub struct TimeSlice { } impl TimeSlice { - pub fn new(time: T, p_draw: f64, convergence: crate::ConvergenceOptions) -> Self { + pub(crate) fn new(time: T, p_draw: f64, convergence: crate::ConvergenceOptions) -> Self { Self { events: Vec::new(), skills: SkillStore::new(), @@ -282,7 +282,7 @@ impl TimeSlice { ); } - pub fn add_events>( + pub(crate) fn add_events>( &mut self, composition: Vec>>, results: Option>>, @@ -393,7 +393,11 @@ impl TimeSlice { /// Panics if an event references a competitor with no entry in this /// slice's skill store. `add_events` inserts one for every participant, so /// this cannot happen for slices built through the public API. - pub fn iteration>(&mut self, from: usize, competitors: &CompetitorStore) { + pub(crate) fn iteration>( + &mut self, + from: usize, + competitors: &CompetitorStore, + ) { if from == 0 && self.color_groups_dirty { self.recompute_color_groups(); } @@ -782,7 +786,7 @@ impl TimeSlice { /// Test-only: reads the slice's shape back for assertions. #[cfg(test)] - pub fn get_composition(&self) -> Vec>> { + pub(crate) fn get_composition(&self) -> Vec>> { self.events .iter() .map(|event| { @@ -802,7 +806,7 @@ impl TimeSlice { /// Test-only: reads the slice's shape back for assertions. #[cfg(test)] - pub fn get_results(&self) -> Vec> { + pub(crate) fn get_results(&self) -> Vec> { self.events .iter() .map(|event| {