1use crate::{CapabilityId, Config, ConfigError, IdError};
3use std::collections::BTreeMap;
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[non_exhaustive]
9pub enum Reason {
10 Missing,
12 Wrong,
14 Untested,
16}
17
18impl Reason {
19 pub fn as_str(self) -> &'static str {
21 match self {
22 Reason::Missing => "missing",
23 Reason::Wrong => "wrong",
24 Reason::Untested => "untested",
25 }
26 }
27}
28
29impl fmt::Display for Reason {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.write_str(self.as_str())
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
37#[non_exhaustive]
38pub enum ParseError {
39 NoHeader,
41 MissingColumn(&'static str),
43 FieldCount {
45 line: usize,
46 want: usize,
47 got: usize,
48 },
49 BadId { line: usize, error: IdError },
51 BadConfig {
53 line: usize,
54 column: &'static str,
55 error: ConfigError,
56 },
57 BadEnabled { line: usize, value: String },
59 BadReason { line: usize, value: String },
61 ReasonMismatch { line: usize },
63 DuplicateColumn(String),
65 BadTimestamp { line: usize, value: String },
67 Other(String),
69}
70
71impl fmt::Display for ParseError {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 ParseError::NoHeader => write!(f, "matrix has no header line"),
75 ParseError::MissingColumn(c) => write!(f, "matrix header lacks column {c:?}"),
76 ParseError::FieldCount { line, want, got } => {
77 write!(f, "line {line}: {got} fields, header has {want}")
78 }
79 ParseError::BadId { line, error } => write!(f, "line {line}: subject: {error}"),
80 ParseError::BadConfig {
81 line,
82 column,
83 error,
84 } => write!(f, "line {line}: {column}: {error}"),
85 ParseError::BadEnabled { line, value } => {
86 write!(f, "line {line}: enabled is {value:?}, want yes or no")
87 }
88 ParseError::BadReason { line, value } => {
89 write!(f, "line {line}: reason {value:?} is unknown")
90 }
91 ParseError::ReasonMismatch { line } => {
92 write!(
93 f,
94 "line {line}: a no needs a reason and a yes must have none"
95 )
96 }
97 ParseError::DuplicateColumn(c) => write!(f, "matrix header names column {c:?} twice"),
98 ParseError::BadTimestamp { line, value } => {
99 write!(
100 f,
101 "line {line}: probed_at {value:?} is not YYYY-MM-DDTHH:MM:SSZ"
102 )
103 }
104 ParseError::Other(m) => f.write_str(m),
105 }
106 }
107}
108
109impl std::error::Error for ParseError {}
110
111#[derive(Debug, Clone, PartialEq, Eq)]
113pub struct Row {
114 pub subject_kind: String,
116 pub subject: CapabilityId,
118 pub backend: String,
120 pub version: String,
122 pub config: Config,
124 pub enabled: bool,
126 pub reason: Option<Reason>,
128 pub metadata: Config,
130 pub note: String,
132 pub extra: BTreeMap<String, String>,
134}