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}