Skip to main content

fallow_types/
churn.rs

1//! Shared churn output contracts.
2
3/// Churn trend indicator based on comparing recent vs older halves of the
4/// analysis period.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, bitcode::Encode, bitcode::Decode)]
6#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
7#[serde(rename_all = "snake_case")]
8pub enum ChurnTrend {
9    /// Recent half has >1.5x the commits of the older half.
10    Accelerating,
11    /// Churn is roughly stable between halves.
12    Stable,
13    /// Recent half has <0.67x the commits of the older half.
14    Cooling,
15}
16
17impl std::fmt::Display for ChurnTrend {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            Self::Accelerating => write!(f, "accelerating"),
21            Self::Stable => write!(f, "stable"),
22            Self::Cooling => write!(f, "cooling"),
23        }
24    }
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30
31    #[test]
32    fn churn_trend_display_matches_wire_values() {
33        assert_eq!(ChurnTrend::Accelerating.to_string(), "accelerating");
34        assert_eq!(ChurnTrend::Stable.to_string(), "stable");
35        assert_eq!(ChurnTrend::Cooling.to_string(), "cooling");
36    }
37
38    #[test]
39    fn churn_trend_serializes_as_snake_case() {
40        assert_eq!(
41            serde_json::to_string(&ChurnTrend::Accelerating).unwrap(),
42            r#""accelerating""#,
43        );
44        assert_eq!(
45            serde_json::to_string(&ChurnTrend::Stable).unwrap(),
46            r#""stable""#,
47        );
48        assert_eq!(
49            serde_json::to_string(&ChurnTrend::Cooling).unwrap(),
50            r#""cooling""#,
51        );
52    }
53}