Skip to main content

tablo_core/declaration/
field_rule.rs

1//! The declaration mistakes of a field's rules, and their wording.
2
3use std::fmt;
4
5/// Why a field's declared rules cannot work:
6/// [`DeclarationErrorKind::FieldRule`](super::DeclarationErrorKind::FieldRule).
7#[derive(Debug, Clone, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum FieldRuleFault {
10    /// A `min` or `max` that is no value the field's type parses, or a type without an order.
11    ///
12    /// Bound a number, date, time or timestamp field by a value of its type.
13    UnorderedBound(String),
14    /// A `pattern` the server does not compile, with the compiler's reason.
15    ///
16    /// Fix the pattern.
17    InvalidPattern(String),
18    /// A `min_length` above the `max_length`, or a `min` above the `max`: no value passes.
19    ///
20    /// Lower the minimum or raise the maximum.
21    EmptyRange,
22    /// A default that breaks a rule, so a create that keeps it is refused.
23    ///
24    /// Change the default or the rule.
25    RefusedDefault(String),
26    /// A default the field's type does not parse, as a timestamp spelled without an offset, so a
27    /// create that keeps it is refused.
28    ///
29    /// Spell the default as the type does, or pass a value of the type.
30    UnparsedDefault(String),
31    /// A rich text editor over a field whose type is no text, as a number or a timestamp,
32    /// carrying the input type its text control had.
33    NotText(&'static str),
34    /// `accepted` on a control other than the built-in checkbox or switch.
35    NotCheckbox,
36    /// `min_items` or `max_items` on a choice that is not `multiple`.
37    SingleValue,
38    /// A multiple choice's `min_items` above the count of static options it offers, carried.
39    FewerOptions(usize),
40    /// A repeater's `max_items` above [`MAX_REPEATER_ROWS`](crate::MAX_REPEATER_ROWS),
41    /// carried.
42    AboveRowCap(usize),
43    /// A field always disabled, with no default, whose blank answer breaks its own rules: an
44    /// `accepted` checkbox or a `min_items`, so every create is refused.
45    RefusedBlank,
46    /// A comparison with a field the schema does not place, carried.
47    ///
48    /// Place the compared field in the same schema, or in the same repeater row.
49    UnplacedComparedField(String),
50    /// A comparison with a field that is no text field of the same type, carried.
51    ///
52    /// Compare two fields of one type: an `Option<T>` field compares with a `T` one.
53    IncomparableField(String),
54    /// An ordering comparison over a type without an order, carrying the compared field.
55    ///
56    /// Order a number, date, time or timestamp field, or compare with `different`.
57    UnorderedComparison(String),
58    /// A comparison with the declaring field itself, so `gt` and `lt` refuse every value and the
59    /// others none.
60    ///
61    /// Compare with another field.
62    SelfComparison,
63    /// A file field's `extensions` listing none, so it refuses every file.
64    ///
65    /// List the extensions it takes, or drop `extensions` to take any.
66    NoExtension,
67    /// A file field's extension that is not letters and digits, carried: `tar.gz` or `*`, which
68    /// no file's last extension is, as the rule reads only the last.
69    ///
70    /// List the last extension alone: `gz`.
71    InvalidExtension(String),
72    /// A file field's `max_bytes` at or above the 10 MiB form-body cap, carried: the body cap
73    /// refuses a larger file first, so the rule never refuses one.
74    ///
75    /// Lower `max_bytes` below 10 MiB.
76    AboveFormCap(usize),
77}
78
79/// [`DeclarationErrorKind::FieldRule`](super::DeclarationErrorKind::FieldRule)'s sentence.
80pub(super) fn fmt_field_rule(
81    f: &mut fmt::Formatter<'_>,
82    field: &str,
83    fault: &FieldRuleFault,
84) -> fmt::Result {
85    match fault {
86        FieldRuleFault::UnorderedBound(bound) => write!(
87            f,
88            "field '{field}' is bounded by '{bound}', which is no value of a type that orders: \
89             bound a number, date, time or timestamp field by a value of its type"
90        ),
91        FieldRuleFault::InvalidPattern(error) => write!(
92            f,
93            "field '{field}' has a pattern that does not compile: {error}"
94        ),
95        FieldRuleFault::EmptyRange => write!(
96            f,
97            "field '{field}' declares a minimum above its maximum, so it refuses every value"
98        ),
99        FieldRuleFault::RefusedDefault(value) => write!(
100            f,
101            "field '{field}' defaults to '{value}', which its own rules refuse: change the default \
102             or the rule"
103        ),
104        FieldRuleFault::UnparsedDefault(value) => write!(
105            f,
106            "field '{field}' defaults to '{value}', which is no value of its type: spell the \
107             default as the type does, or pass a value of the type"
108        ),
109        FieldRuleFault::NotText(input) => write!(
110            f,
111            "field '{field}' is a rich text editor over a field its form edits as '{input}' \
112             input, but rich text stores HTML: make the field a `String` or `Option<String>`"
113        ),
114        FieldRuleFault::NotCheckbox => write!(
115            f,
116            "field '{field}' is `accepted` but is not the built-in checkbox or switch: declare \
117             it with `Field::toggle` or `Field::toggle_input`"
118        ),
119        FieldRuleFault::SingleValue => write!(
120            f,
121            "field '{field}' bounds how many options it takes, but takes one: make it `multiple` \
122             or drop `min_items` and `max_items`"
123        ),
124        FieldRuleFault::FewerOptions(options) => write!(
125            f,
126            "field '{field}' needs more options chosen than the {options} it offers, so it \
127             refuses every value"
128        ),
129        FieldRuleFault::AboveRowCap(max) => write!(
130            f,
131            "field '{field}' takes up to {max} rows, more than any repeater takes \
132             (`MAX_REPEATER_ROWS`): lower `max_items`"
133        ),
134        FieldRuleFault::RefusedBlank => write!(
135            f,
136            "field '{field}' is disabled and has no default, but its own rules refuse its blank \
137             answer, so every create is refused: give it a default or drop the rule"
138        ),
139        FieldRuleFault::UnplacedComparedField(other) => write!(
140            f,
141            "field '{field}' compares with field '{other}', which the schema does not place: \
142             place it in the same schema, or in the same repeater row"
143        ),
144        FieldRuleFault::IncomparableField(other) => write!(
145            f,
146            "field '{field}' compares with field '{other}', which is not a text field of the same \
147             type: compare two fields of one type"
148        ),
149        FieldRuleFault::UnorderedComparison(other) => write!(
150            f,
151            "field '{field}' orders against field '{other}', but its type has no order: compare \
152             a number, date, time or timestamp field, or use `different`"
153        ),
154        FieldRuleFault::SelfComparison => write!(
155            f,
156            "field '{field}' compares with itself: compare it with another field"
157        ),
158        FieldRuleFault::NoExtension => write!(
159            f,
160            "field '{field}' lists no extension it takes, so it refuses every file: list one, or \
161             drop `extensions`"
162        ),
163        FieldRuleFault::InvalidExtension(extension) => write!(
164            f,
165            "field '{field}' takes the extension '{extension}', but a file's extension is the \
166             last one alone, in letters and digits: list that one"
167        ),
168        FieldRuleFault::AboveFormCap(max) => write!(
169            f,
170            "field '{field}' takes files up to {max} bytes, but a form body holds at most 10 MiB: \
171             lower `max_bytes` below it"
172        ),
173    }
174}