Skip to main content

git_bot_feedback/
file_annotations.rs

1#[cfg(feature = "pyo3")]
2use pyo3::prelude::*;
3
4/// A structure to describe the output of a file annotation.
5#[derive(Debug, Default, Clone)]
6#[cfg_attr(
7    feature = "pyo3",
8    pyclass(module = "git_bot_feedback", from_py_object, get_all, set_all)
9)]
10pub struct FileAnnotation {
11    /// The severity level of the annotation.
12    pub severity: AnnotationLevel,
13
14    /// The path to the file being annotated.
15    ///
16    /// This is relative to the repository root.
17    /// It should not start with a leading slash (not `./`).
18    /// It should only use posix-style path separators (`/`), even on Windows runners.
19    ///
20    /// On Github, this can be left blank if the annotation is to be specific to the workflow run.
21    pub path: String,
22
23    /// The line number where the annotation starts (1-based).
24    ///
25    /// If not provided, the annotation will be scoped to the entire file (and [`Self::end_line`] will be ignored).
26    ///
27    /// This is ignored if [`Self::path`] is blank.
28    pub start_line: Option<usize>,
29
30    /// The line number where the annotation ends (1-based).
31    ///
32    /// If not provided, the annotation will be placed at the specified [`Self::start_line`] instead.
33    ///
34    /// This is ignored if
35    ///
36    /// - [`Self::path`] is blank.
37    /// - [`Self::start_line`] is not provided.
38    /// - [`Self::end_line`] is not greater than [`Self::start_line`].
39    pub end_line: Option<usize>,
40
41    /// The column number where the annotation starts (1-based).
42    ///
43    /// This is ignored if the [`Self::start_line`] is not provided,
44    /// or if [`Self::path`] is blank.
45    pub start_column: Option<usize>,
46
47    /// The column number where the annotation ends (1-based).
48    ///
49    /// This is ignored if
50    ///
51    /// - the [`Self::path`] is blank
52    /// - the [`Self::start_line`] is not provided
53    /// - the [`Self::end_line`] is not greater than [`Self::start_line`]
54    ///   and [`Self::start_column`] is provided
55    ///   but is not less than this [`Self::end_column`]
56    pub end_column: Option<usize>,
57
58    /// The title of the annotation, which will be shown in the Git Server's UI.
59    pub title: Option<String>,
60
61    /// The message of the annotation, which will be shown in the Git Server's UI.
62    ///
63    /// This shall not contain any line breaks.
64    /// Some Git Servers may support a limited set of markdown syntax, but this is not guaranteed.
65    pub message: String,
66}
67
68#[cfg(feature = "pyo3")]
69#[pymethods]
70impl FileAnnotation {
71    /// Create a new file annotation instance.
72    #[new]
73    #[allow(clippy::too_many_arguments)]
74    #[pyo3(
75        signature = (severity, path, message, start_line=None, end_line=None, start_column=None, end_column=None, title=None),
76        text_signature = "(severity: AnnotationLevel, path: str, message: str, start_line: int | None = None, end_line: int | None = None, start_column: int | None = None, end_column: int | None = None, title: str | None = None)"
77    )]
78    pub fn new_py(
79        severity: AnnotationLevel,
80        path: String,
81        message: String,
82        start_line: Option<usize>,
83        end_line: Option<usize>,
84        start_column: Option<usize>,
85        end_column: Option<usize>,
86        title: Option<String>,
87    ) -> Self {
88        Self {
89            severity,
90            path,
91            start_line,
92            end_line,
93            start_column,
94            end_column,
95            title,
96            message,
97        }
98    }
99}
100
101/// The severity of a [`FileAnnotation`].
102#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
103#[cfg_attr(
104    feature = "pyo3",
105    pyclass(module = "git_bot_feedback", from_py_object, eq)
106)]
107pub enum AnnotationLevel {
108    /// The annotation is for debugging purposes.
109    Debug,
110    /// The annotation is for informational purposes.
111    #[default]
112    Notice,
113    /// The annotation is for warning purposes.
114    Warning,
115    /// The annotation is for error purposes.
116    Error,
117}