Skip to main content

rite_model/params/
entry.rs

1//! Params for the `enter_value` and `enter_secret` actions.
2
3use schemars::{JsonSchema, Schema};
4use serde::{Deserialize, Serialize};
5use serde_json::json;
6
7use super::FormatSpec;
8use super::schema::add_rule;
9
10/// Params for the `enter_value` and `enter_secret` actions.
11///
12/// The shape fields are turned into one rule by
13/// [`EntryShape`](super::EntryShape), which is also what
14/// `rite check` applies to them.
15#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
16#[serde(deny_unknown_fields)]
17#[schemars(transform = one_rule)]
18#[non_exhaustive]
19pub struct EntryParams {
20    /// What the person is asked for, shown at the prompt.
21    pub message: String,
22    /// What kind of value it is: a format name, or `{ pattern: "..." }`.
23    /// Text by default. An encoding makes the artifact the decoded bytes.
24    #[serde(default)]
25    pub format: Option<FormatSpec>,
26    /// An exact length, in characters for text and bytes for an encoding.
27    #[serde(default)]
28    #[schemars(range(min = 1))]
29    pub length: Option<usize>,
30    /// The fewest units accepted.
31    #[serde(default)]
32    #[schemars(range(min = 1))]
33    pub min_length: Option<usize>,
34    /// The most units accepted.
35    #[serde(default)]
36    #[schemars(range(min = 1))]
37    pub max_length: Option<usize>,
38}
39
40/// The fields describe one rule: an exact length stands alone, and a pattern
41/// says the whole shape. The rules that compare two values are
42/// [`EntryShape::validator`](super::EntryShape::validator)'s.
43fn one_rule(schema: &mut Schema) {
44    let absent = |fields: &[&str]| -> Vec<serde_json::Value> {
45        fields
46            .iter()
47            .map(|field| json!({ "not": { "required": [field] } }))
48            .collect()
49    };
50    add_rule(
51        schema,
52        json!({
53            "if": { "required": ["length"] },
54            "then": {
55                "allOf": absent(&["min_length", "max_length"]),
56                "x-message": "'length' is exact, so 'min_length' and 'max_length' cannot be \
57                    given beside it",
58            },
59        }),
60    );
61    add_rule(
62        schema,
63        json!({
64            "if": {
65                "properties": { "format": { "type": "object" } },
66                "required": ["format"],
67            },
68            "then": {
69                "allOf": absent(&["length", "min_length", "max_length"]),
70                "x-message": "a pattern says the whole shape of the value, so 'length', \
71                    'min_length' and 'max_length' cannot be given beside it",
72            },
73        }),
74    );
75}