Skip to content

Commit e5f742a

Browse files
authored
Refactor InvalidSchemaError to support multiple errors (#246)
* Move result.rs -> result/mod.rs * Refactor InvalidSchemaError
1 parent de8bafc commit e5f742a

30 files changed

+614
-392
lines changed

ion-schema/src/constraint.rs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@ use crate::isl::util::{
1111
Annotation, Ieee754InterchangeFormat, TimestampOffset, TimestampPrecision, ValidValue,
1212
};
1313
use crate::isl::IslVersion;
14-
use crate::isl_require;
1514
use crate::ordered_elements_nfa::OrderedElementsNfa;
16-
use crate::result::{
17-
invalid_schema_error, invalid_schema_error_raw, IonSchemaResult, ValidationResult,
18-
};
15+
use crate::result::{invalid_schema, isl_require, IonSchemaResult, ValidationResult};
1916
use crate::system::{PendingTypes, TypeId, TypeStore};
2017
use crate::type_reference::{TypeReference, VariablyOccurringTypeRef};
2118
use crate::types::TypeValidator;
@@ -1916,9 +1913,7 @@ impl RegexConstraint {
19161913
.case_insensitive(isl_regex.case_insensitive())
19171914
.multi_line(isl_regex.multi_line())
19181915
.build()
1919-
.map_err(|e| {
1920-
invalid_schema_error_raw(format!("Invalid regex {}", isl_regex.expression()))
1921-
})?;
1916+
.map_err(|e| invalid_schema!("Invalid regex {}", isl_regex.expression()))?;
19221917

19231918
Ok(RegexConstraint::new(
19241919
regex,
@@ -1948,7 +1943,7 @@ impl RegexConstraint {
19481943
sb.push(ch);
19491944
if let Some(ch) = si.next() {
19501945
if ch == '?' {
1951-
return invalid_schema_error(format!("invalid character {ch}"));
1946+
return invalid_schema!("invalid character {ch}");
19521947
}
19531948
sb.push(ch)
19541949
}
@@ -1965,11 +1960,7 @@ impl RegexConstraint {
19651960
}
19661961
's' => sb.push_str("[ \\f\\n\\r\\t]"),
19671962
'S' => sb.push_str("[^ \\f\\n\\r\\t]"),
1968-
_ => {
1969-
return invalid_schema_error(format!(
1970-
"invalid escape character {ch}",
1971-
))
1972-
}
1963+
_ => return invalid_schema!("invalid escape character {ch}",),
19731964
}
19741965
}
19751966
}
@@ -1993,10 +1984,10 @@ impl RegexConstraint {
19931984
match ch {
19941985
'&' => {
19951986
if si.peek() == Some(&'&') {
1996-
return invalid_schema_error("'&&' is not supported in a character class");
1987+
return invalid_schema!("'&&' is not supported in a character class");
19971988
}
19981989
}
1999-
'[' => return invalid_schema_error("'[' must be escaped within a character class"),
1990+
'[' => return invalid_schema!("'[' must be escaped within a character class"),
20001991
'\\' => {
20011992
if let Some(ch2) = si.next() {
20021993
match ch2 {
@@ -2006,10 +1997,10 @@ impl RegexConstraint {
20061997
match isl_version {
20071998
IslVersion::V1_0 => {
20081999
// returns an error for ISL 1.0 as it does not support pre-defined char classes (i.e., \d, \s, \w)
2009-
return invalid_schema_error(format!(
2000+
return invalid_schema!(
20102001
"invalid sequence '{:?}' in character class",
20112002
si
2012-
));
2003+
);
20132004
}
20142005
IslVersion::V2_0 => {
20152006
// Change \w and \W to be [a-zA-Z0-9_] and [^a-zA-Z0-9_] respectively
@@ -2028,9 +2019,9 @@ impl RegexConstraint {
20282019
}
20292020
}
20302021
_ => {
2031-
return invalid_schema_error(format!(
2022+
return invalid_schema!(
20322023
"invalid sequence '\\{ch2}' in character class"
2033-
))
2024+
)
20342025
}
20352026
}
20362027
}
@@ -2040,7 +2031,7 @@ impl RegexConstraint {
20402031
}
20412032
}
20422033

2043-
invalid_schema_error("character class missing ']'")
2034+
invalid_schema!("character class missing ']'")
20442035
}
20452036

20462037
fn parse_quantifier(sb: &mut String, si: &mut Peekable<Chars<'_>>) -> IonSchemaResult<()> {
@@ -2069,22 +2060,22 @@ impl RegexConstraint {
20692060
complete = true;
20702061
break;
20712062
}
2072-
_ => return invalid_schema_error(format!("invalid character {ch}")),
2063+
_ => return invalid_schema!("invalid character {ch}"),
20732064
}
20742065
}
20752066

20762067
if !complete {
2077-
return invalid_schema_error("range quantifier missing '}'");
2068+
return invalid_schema!("range quantifier missing '}}'");
20782069
}
20792070
}
20802071
_ => {}
20812072
}
20822073
if sb.len() > initial_length {
20832074
if let Some(ch) = si.peek().cloned() {
20842075
match ch {
2085-
'?' => return invalid_schema_error(format!("invalid character {ch}")),
2076+
'?' => return invalid_schema!("invalid character {ch}"),
20862077

2087-
'+' => return invalid_schema_error(format!("invalid character {ch}")),
2078+
'+' => return invalid_schema!("invalid character {ch}"),
20882079
_ => {}
20892080
}
20902081
}

ion-schema/src/internal_traits.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// TODO: This file is a placeholder. These things will eventually be moved to more sensible locations
55
// instead of being clobbered together.
66

7-
use crate::result::{invalid_schema_error, IonSchemaResult};
7+
use crate::result::{invalid_schema, IonSchemaResult};
88
use crate::{IonSchemaElement, IslVersion, ViolationRecorder};
99
use ion_rs::{Element, ValueWriter};
1010
use std::fmt::Debug;
@@ -44,9 +44,7 @@ pub(crate) trait WriteAsIsl<V: IslVersion>: Debug {
4444
ctx: &WriteContext<V>,
4545
) -> IonSchemaResult<()> {
4646
let (major, minor) = V::MAJOR_MINOR;
47-
invalid_schema_error(format!(
48-
"{self:?} is not supported in Ion Schema Language {major}.{minor}"
49-
))
47+
invalid_schema!("{self:?} is not supported in Ion Schema Language {major}.{minor}")
5048
}
5149
}
5250

ion-schema/src/ion_extension.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use crate::result::{invalid_schema_error, IonSchemaResult};
4+
use crate::result::{invalid_schema, IonSchemaResult};
55
use ion_rs::{Decimal, IonResult, Struct, Symbol};
66
use ion_rs::{Element, Value};
77
use num_traits::ToPrimitive;
@@ -54,7 +54,7 @@ impl ElementExtensions for Element {
5454
let text = symbol.expect_text()?;
5555
match annotations.next() {
5656
None => Ok(Some(text)),
57-
Some(_) => invalid_schema_error(format!("Unexpected annotations: {self}")),
57+
Some(_) => invalid_schema!("Unexpected annotations: {self}"),
5858
}
5959
}
6060

@@ -93,7 +93,7 @@ impl StructExtensions for Struct {
9393
let first = iter.next();
9494
let second = iter.next();
9595
if second.is_some() {
96-
invalid_schema_error(format!("Illegal repeated field '{field_name}' in: {self}"))
96+
invalid_schema!("Illegal repeated field '{field_name}' in: {self}")
9797
} else {
9898
Ok(first)
9999
}
@@ -103,7 +103,7 @@ impl StructExtensions for Struct {
103103
if let Some(element) = self.get_optional(field_name)? {
104104
Ok(element)
105105
} else {
106-
invalid_schema_error(format!("Missing required field '{field_name}' in: {self}"))
106+
invalid_schema!("Missing required field '{field_name}' in: {self}")
107107
}
108108
}
109109
}

ion-schema/src/ion_schema_version.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ use std::marker::PhantomData;
4949

5050
/// Wrapper for data that needs to be passed around with an ISL version—for example, builder methods
5151
/// for some constraints can accept `Versioned<TypeArgument>`s.
52-
///
53-
/// Technically, this is a smart pointer that (rather than managing the ownership or memory of the
54-
/// wrapped value) encodes Ion Schema version information along with the wrapped value.
5552
#[derive(Copy, Clone, PartialEq, Debug)]
5653
pub struct Versioned<T, V: IslVersion>(T, PhantomData<V>);
5754
impl<T, V: IslVersion> Versioned<T, V> {

0 commit comments

Comments
 (0)