rorm_declaration/
lints.rs

1//! Some common lints whose code can be shared between rorm-macro and rorm-cli.
2
3use crate::imr::Annotation;
4
5/// Simple struct storing whether a specific annotation is set on a given field or not.
6#[derive(Copy, Clone, Default, Debug)]
7pub struct Annotations {
8    /// Does the field have the [Annotation::AutoCreateTime]?
9    pub auto_create_time: bool,
10
11    /// Does the field have the [Annotation::AutoUpdateTime]?
12    pub auto_update_time: bool,
13
14    /// Does the field have the [Annotation::AutoIncrement]?
15    pub auto_increment: bool,
16
17    /// Does the field have the [Annotation::Choices]?
18    pub choices: bool,
19
20    /// Does the field have the [Annotation::DefaultValue]?
21    pub default: bool,
22
23    /// Does the field have the [Annotation::Index]?
24    pub index: bool,
25
26    /// Does the field have the [Annotation::MaxLength]?
27    pub max_length: bool,
28
29    /// Does the field have the [Annotation::NotNull]?
30    pub not_null: bool,
31
32    /// Does the field have the [Annotation::PrimaryKey]?
33    pub primary_key: bool,
34
35    /// Does the field have the [Annotation::Unique]?
36    pub unique: bool,
37
38    /// Does the field have the [Annotation::ForeignKey]?
39    pub foreign_key: bool,
40}
41
42impl Annotations {
43    /// Check whether this set of annotations is valid.
44    ///
45    /// Returns a non-empty error message, when it is not.
46    // Disable auto-format to make the following match compacter and more readable.
47    #[rustfmt::skip]
48    pub const fn check(self) -> Result<(), &'static str> {
49        // Alias to reduce line length and noise
50        use Annotations as A;
51
52        let msg = match self {
53            A { auto_create_time: true, auto_increment: true, .. } => "AutoCreateTime and AutoIncrement are mutually exclusive",
54            A { auto_create_time: true, choices: true, .. } => "AutoCreateTime and Choices are mutually exclusive",
55            A { auto_create_time: true, default: true, .. } => "AutoCreateTime and DefaultValue are mutually exclusive",
56            A { auto_create_time: true, max_length: true, .. } => "AutoCreateTime and MaxLength are mutually exclusive",
57            A { auto_create_time: true, primary_key: true, .. } => "AutoCreateTime and PrimaryKey are mutually exclusive",
58            A { auto_create_time: true, unique: true, .. } => "AutoCreateTime and Unique are mutually exclusive",
59            A { auto_update_time: true, auto_increment: true, .. } => "AutoUpdateTime and AutoIncrement are mutually exclusive",
60            A { auto_update_time: true, choices: true, .. } => "AutoUpdateTime and Choices are mutually exclusive",
61            A { auto_update_time: true, max_length: true, .. } => "AutoUpdateTime and MaxLength are mutually exclusive",
62            A { auto_update_time: true, primary_key: true, .. } => "AutoUpdateTime and PrimaryKey are mutually exclusive",
63            A { auto_update_time: true, unique: true, .. } => "AutoUpdateTime and Unique are mutually exclusive",
64            A { auto_increment: true, choices: true, .. } => "AutoIncrement and Choices are mutually exclusive",
65            A { auto_increment: true, max_length: true, .. } => "AutoIncrement and MaxLength are mutually exclusive",
66            A { choices: true, max_length: true, .. } => "Choices and MaxLength are mutually exclusive",
67            A { choices: true, primary_key: true, .. } => "Choices and PrimaryKey are mutually exclusive",
68            A { choices: true, unique: true, .. } => "Choices and Unique are mutually exclusive",
69            A { default: true, auto_update_time: true, .. } => "DefaultValue and AutoUpdateTime are mutually exclusive",
70            A { default: true, auto_increment: true, .. } => "DefaultValue and AutoIncrement are mutually exclusive",
71            A { default: true, primary_key: true, .. } => "DefaultValue and PrimaryKey are mutually exclusive",
72            A { default: true, unique: true, .. } => "DefaultValue and Unique are mutually exclusive",
73            A { index: true, primary_key: true, .. } => "Index and PrimaryKey are mutually exclusive",
74            A { not_null: true, primary_key: true, .. } => "NotNull and PrimaryKey are mutually exclusive",
75
76            A { auto_increment: true, primary_key: false, .. } => "AutoIncrement requires PrimaryKey",
77
78            A { auto_update_time: true, not_null: true, auto_create_time: false, default: false, ..} => "AutoUpdateTime in combination with NotNull requires ether DefaultValue or AutoCreateTime",
79
80            _ => "",
81        };
82
83        // Create Result based on error message length to avoid using Err() in the match expression.
84        if !msg.is_empty() {
85            Err(msg)
86        } else {
87            Ok(())
88        }
89    }
90}
91
92impl From<&[Annotation]> for Annotations {
93    fn from(annotations: &[Annotation]) -> Self {
94        let mut result = Annotations::default();
95        for annotation in annotations {
96            match annotation {
97                Annotation::AutoCreateTime => result.auto_create_time = true,
98                Annotation::AutoUpdateTime => result.auto_update_time = true,
99                Annotation::AutoIncrement => result.auto_increment = true,
100                Annotation::Choices(_) => result.choices = true,
101                Annotation::DefaultValue(_) => result.default = true,
102                Annotation::Index(_) => result.index = true,
103                Annotation::MaxLength(_) => result.max_length = true,
104                Annotation::NotNull => result.not_null = true,
105                Annotation::PrimaryKey => result.primary_key = true,
106                Annotation::Unique => result.unique = true,
107                Annotation::ForeignKey(_) => result.foreign_key = true,
108            }
109        }
110        result
111    }
112}