1use serde::Serializer;
2use sha2::Digest;
3
4pub mod annotations;
5mod encoding;
6pub mod product;
7pub mod report;
8pub mod requirements;
9pub mod reviews;
10pub mod test_runs;
11
12pub use relative_path as path;
13pub use time;
14
15pub const SCHEMA_VERSION: &str = env!("CARGO_PKG_VERSION");
18
19pub const PRODUCTS_FOLDER_NAME: &str = "products";
20pub const REQUIREMENTS_FOLDER_NAME: &str = "requirements";
21pub const REVIEWS_FOLDER_NAME: &str = "reviews";
22pub const TEST_RUNS_FOLDER_NAME: &str = "test-runs";
23pub const SOURCES_FOLDER_NAME: &str = "sources";
24
25pub type Line = i64;
28pub type Origin = serde_json::Value;
29pub type Properties = serde_json::value::Map<String, serde_json::Value>;
30
31#[derive(
32 Debug,
33 Clone,
34 Copy,
35 PartialEq,
36 Eq,
37 Hash,
38 serde::Serialize,
39 serde::Deserialize,
40 schemars::JsonSchema,
41)]
42#[serde(deny_unknown_fields)]
43pub struct LineSpan {
44 pub start: Line,
45 pub end: Line,
46}
47
48fn serialize_schema_version<S>(_value: &Option<String>, ser: S) -> Result<S::Ok, S::Error>
49where
50 S: Serializer,
51{
52 ser.serialize_str(SCHEMA_VERSION)
53}
54
55#[derive(
56 Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
57)]
58#[serde(deny_unknown_fields)]
59pub struct Revision {
60 pub nr: i64,
61 pub authors: Vec<String>,
62 pub comment: String,
63}
64
65#[derive(
66 Debug,
67 Clone,
68 PartialEq,
69 Eq,
70 Hash,
71 sqlx::Type,
72 serde::Serialize,
73 serde::Deserialize,
74 schemars::JsonSchema,
75)]
76#[sqlx(transparent)]
78#[serde(transparent)]
79pub struct FmtHash(String);
80
81impl FmtHash {
82 pub fn hash(&self) -> &str {
83 &self.0
84 }
85
86 pub fn new(s: &str) -> Self {
87 let mut hash = sha2::Sha256::new();
88 hash.update(s.as_bytes());
89 Self(base16ct::lower::encode_string(&hash.finalize()))
90 }
91
92 pub fn with_inner(hash: String) -> Self {
93 Self(hash)
94 }
95}
96
97impl std::fmt::Display for FmtHash {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "{}", self.0)
100 }
101}
102
103impl<S: serde::Serialize> From<&S> for FmtHash {
104 fn from(value: &S) -> Self {
105 let content = serde_json::to_string(value).expect(
106 "Types that implement serde::Serialize should never fail to serialize to JSON.",
107 );
108 Self::new(&content)
109 }
110}
111
112impl std::str::FromStr for FmtHash {
113 type Err = ();
114
115 fn from_str(s: &str) -> Result<Self, Self::Err> {
116 Ok(Self::new(s))
117 }
118}
119
120#[derive(Debug, thiserror::Error)]
121pub enum ConversionError {
122 #[error("Number does not match to a known kind.")]
123 UnknownKind,
124 #[error("Number does not match to a known state.")]
125 UnknownState,
126 #[error("Given format is unknown")]
127 UnknownFormat,
128}
129
130#[derive(Debug, thiserror::Error)]
131pub enum IdentError {
132 #[error("Given ID contains invalid characters.")]
133 InvalidCharacter,
134}