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}