Skip to main content

nmp_threading/
policy.rs

1//! `ModulePolicy` — knobs for the grouping algorithm. Spec carries one per
2//! view instance so the same crate can serve different threading styles
3//! (tight modules vs. longer ancestor chains) without an algorithmic fork.
4
5use serde::{Deserialize, Serialize};
6
7/// Tunables for [`crate::Grouper`]. Defaults mirror Twitter / X behaviour:
8/// at most three messages per module, ancestor walk capped at two hops,
9/// adjacent same-root modules merged.
10#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
11pub struct ModulePolicy {
12    /// Maximum events surfaced inside a single `TimelineBlock::Module`.
13    /// Excess is rendered as additional standalone or chained modules.
14    pub max_module_size: u8,
15    /// Time gap (seconds) between adjacent module events before the block
16    /// is marked `has_gap = true`. Defaults to 72h.
17    pub max_lookback_gap_secs: u64,
18    /// How many ancestor hops to walk when stitching a reply into its
19    /// parent chain. `Address` / `External` pointers terminate the walk
20    /// regardless of the remaining budget.
21    pub max_ancestor_hops: u8,
22    /// Whether adjacent modules that share the same root pointer should be
23    /// merged into one block (Twitter-style "this is the same thread").
24    pub collapse_adjacent_same_root: bool,
25}
26
27impl Default for ModulePolicy {
28    fn default() -> Self {
29        Self {
30            max_module_size: 3,
31            max_lookback_gap_secs: 72 * 3600,
32            max_ancestor_hops: 2,
33            collapse_adjacent_same_root: true,
34        }
35    }
36}