|
1 | 1 | /// This module implements various inspections which can be performed over Shapes. |
2 | 2 | use super::*; |
3 | 3 | use crate::reduce::Strategy; |
4 | | -use json::{LocatedProperty, Location}; |
| 4 | +use json::{schema::formats::Format, LocatedProperty, Location}; |
5 | 5 |
|
6 | 6 | #[derive(thiserror::Error, Debug, Eq, PartialEq)] |
7 | 7 | pub enum Error { |
8 | 8 | #[error("'{0}' must exist, but is constrained to always be invalid")] |
9 | 9 | ImpossibleMustExist(String), |
10 | 10 | #[error("'{0}' has reduction strategy, but its parent does not")] |
11 | 11 | ChildWithoutParentReduction(String), |
12 | | - #[error("{0} has 'sum' reduction strategy, restricted to numbers, but has types {1:?}")] |
| 12 | + #[error("{0} has 'sum' reduction strategy (restricted to integers, numbers and strings with `format: integer` or `format: number`) but has types {1:?}")] |
13 | 13 | SumNotNumber(String, types::Set), |
14 | 14 | #[error( |
15 | 15 | "{0} has 'merge' reduction strategy, restricted to objects & arrays, but has types {1:?}" |
@@ -80,13 +80,14 @@ impl Shape { |
80 | 80 | } |
81 | 81 | }; |
82 | 82 |
|
83 | | - if matches!(self.reduction, Reduction::Strategy(Strategy::Sum)) |
84 | | - && self.type_ - types::INT_OR_FRAC != types::INVALID |
85 | | - { |
86 | | - out.push(Error::SumNotNumber( |
87 | | - loc.pointer_str().to_string(), |
88 | | - self.type_, |
89 | | - )); |
| 83 | + if matches!(self.reduction, Reduction::Strategy(Strategy::Sum)) { |
| 84 | + match (self.type_ - types::INT_OR_FRAC, &self.string.format) { |
| 85 | + (types::INVALID, _) => (), // Okay (native numeric only). |
| 86 | + (types::STRING, Some(Format::Number) | Some(Format::Integer)) => (), // Okay (string-formatted numeric). |
| 87 | + (type_, _) => { |
| 88 | + out.push(Error::SumNotNumber(loc.pointer_str().to_string(), type_)); |
| 89 | + } |
| 90 | + } |
90 | 91 | } |
91 | 92 | if matches!(self.reduction, Reduction::Strategy(Strategy::Merge(_))) |
92 | 93 | && self.type_ - (types::OBJECT | types::ARRAY) != types::INVALID |
@@ -145,6 +146,11 @@ mod test { |
145 | 146 | type: object |
146 | 147 | reduce: {strategy: merge} |
147 | 148 | properties: |
| 149 | + sum-right-type: |
| 150 | + reduce: {strategy: sum} |
| 151 | + type: [number, string] |
| 152 | + format: integer |
| 153 | +
|
148 | 154 | sum-wrong-type: |
149 | 155 | reduce: {strategy: sum} |
150 | 156 | type: [number, string] |
@@ -207,10 +213,7 @@ mod test { |
207 | 213 | Error::SetInvalidProperty("/-/whoops2".to_owned()), |
208 | 214 | Error::ImpossibleMustExist("/must-exist-but-cannot".to_owned()), |
209 | 215 | Error::ImpossibleMustExist("/nested-array/1".to_owned()), |
210 | | - Error::SumNotNumber( |
211 | | - "/sum-wrong-type".to_owned(), |
212 | | - types::INT_OR_FRAC | types::STRING |
213 | | - ), |
| 216 | + Error::SumNotNumber("/sum-wrong-type".to_owned(), types::STRING), |
214 | 217 | Error::MergeNotObjectOrArray("/merge-wrong-type".to_owned(), types::BOOLEAN), |
215 | 218 | Error::ChildWithoutParentReduction("/*/nested-sum".to_owned()), |
216 | 219 | ] |
|
0 commit comments