backhopper_core/model/pr_commit.rs
1// Copyright (C) 2026 Michael S. Klishin and Contributors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// See LICENSE-APACHE and LICENSE-MIT for details.
4
5//! Inner PR-branch commits enumerated under a 2-parent merge.
6
7use serde::{Deserialize, Serialize};
8use time::OffsetDateTime;
9
10use crate::model::names::CommitSha;
11
12/// One commit on the PR-branch side of a 2-parent merge.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
15pub struct PrCommit {
16 pub sha: CommitSha,
17 pub subject: String,
18 #[cfg_attr(feature = "schemars", schemars(with = "String"))]
19 #[serde(with = "time::serde::rfc3339")]
20 pub author_date: OffsetDateTime,
21 pub kind: PrCommitKind,
22}
23
24/// Classification of a PR-branch commit's role.
25///
26/// `#[non_exhaustive]` so future, richer taxonomies (test-only,
27/// docs-only, dependency-bump, etc.) can add variants without a
28/// breaking change.
29#[non_exhaustive]
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
31#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
32#[serde(rename_all = "snake_case")]
33pub enum PrCommitKind {
34 /// Default: substantive change worth reviewing.
35 Substantive,
36 /// Subject matched the conflict-resolution catalog AND the file
37 /// set was a strict subset of prior PR-branch commits.
38 ConflictResolution,
39 /// Subject indicated the commit applied code-review feedback.
40 ReviewFeedback,
41 /// `git --fixup` auto-generated or the manual `fixup:` convention.
42 Fixup,
43 /// Subject was `WIP` or bare `Cleanup`.
44 WipOrCleanup,
45}
46
47impl PrCommitKind {
48 /// True when the kind is anything other than `Substantive`. Useful
49 /// shorthand for "skip this row by default."
50 #[must_use]
51 pub fn is_likely_bookkeeping(self) -> bool {
52 !matches!(self, Self::Substantive)
53 }
54}