siderite_cli/check/
mod.rs1mod backend;
17pub(crate) mod config;
18mod migrations;
19mod models;
20mod openapi;
21
22use crate::settings::CliSettings;
23use siderite_core::App;
24use siderite_orm::ModelMeta;
25use std::fmt;
26use std::path::Path;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
30pub enum CheckLevel {
31 Warning,
33 Error,
35}
36
37impl fmt::Display for CheckLevel {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 f.write_str(match self {
40 Self::Warning => "warning",
41 Self::Error => "error",
42 })
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct CheckIssue {
49 pub level: CheckLevel,
51 pub id: &'static str,
53 pub message: String,
55}
56
57impl CheckIssue {
58 pub fn error(id: &'static str, message: impl Into<String>) -> Self {
60 Self {
61 level: CheckLevel::Error,
62 id,
63 message: message.into(),
64 }
65 }
66
67 pub fn warning(id: &'static str, message: impl Into<String>) -> Self {
69 Self {
70 level: CheckLevel::Warning,
71 id,
72 message: message.into(),
73 }
74 }
75}
76
77impl fmt::Display for CheckIssue {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 write!(f, "{}: [{}] {}", self.level, self.id, self.message)
80 }
81}
82
83pub fn has_errors(issues: &[CheckIssue]) -> bool {
85 issues.iter().any(|i| i.level == CheckLevel::Error)
86}
87
88pub fn check(
94 app: &App,
95 models: &[&'static ModelMeta],
96 settings: &CliSettings,
97 migrations_dir: Option<&Path>,
98) -> Vec<CheckIssue> {
99 let mut issues = Vec::new();
100 issues.extend(config::check(models, settings));
101 issues.extend(models::check(models));
102 if let Some(dir) = migrations_dir {
103 issues.extend(migrations::check(models, dir));
104 }
105 issues.extend(openapi::check(app));
106 issues.extend(backend::check(models, settings));
107 issues
108}
109
110pub fn check_build(app: App) -> Vec<CheckIssue> {
114 openapi::check_build(app)
115}
116
117pub(crate) fn has_managed_models(models: &[&'static ModelMeta]) -> bool {
119 models.iter().any(|m| m.managed)
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn issues_display_level_id_and_message() {
128 let issue = CheckIssue::error("models.E001", "boom");
129 assert_eq!(issue.to_string(), "error: [models.E001] boom");
130 let issue = CheckIssue::warning("migrations.W001", "meh");
131 assert_eq!(issue.to_string(), "warning: [migrations.W001] meh");
132 }
133
134 #[test]
135 fn has_errors_ignores_warnings() {
136 let warn = CheckIssue::warning("x.W001", "w");
137 assert!(!has_errors(std::slice::from_ref(&warn)));
138 assert!(has_errors(&[warn, CheckIssue::error("x.E001", "e")]));
139 assert!(CheckLevel::Warning < CheckLevel::Error);
140 }
141}