ion_schema/
result.rs

1//! Represents the [`IonSchemaResult`] type for error handling.
2//!
3//! [`IonSchemaResult<T, E>`][`IonSchemaResult`]  is the type used for returning and propagating errors.
4//! It is an enum with the variants, Ok(T), representing success and containing a value,and Err(E), representing an [`IonSchemaError`].
5
6use crate::violation::Violation;
7use ion_rs::IonError;
8use std::io;
9use thiserror::Error;
10
11/// A unified Result type representing the outcome of method calls that may fail.
12pub type IonSchemaResult<T> = Result<T, IonSchemaError>;
13
14/// A Result type representing the outcome of validation that may result in violations.
15pub type ValidationResult = Result<(), Violation>;
16
17/// Represents the different types of high-level failures that might occur when reading Ion Schema.
18#[derive(Debug, Error)]
19pub enum IonSchemaError {
20    /// Indicates that an io error occurred while loading a schema
21    #[error("{source:?}")]
22    IoError {
23        #[from]
24        source: io::Error,
25    },
26
27    /// Indicates failure for schema which has unresolvable imports/types
28    #[error("{description}")]
29    UnresolvableSchemaError { description: String },
30
31    /// Indicates failure due to invalid schema syntax
32    #[error("{description}")]
33    InvalidSchemaError { description: String },
34
35    /// Indicates failure due to ion-rust error defined by IonError
36    #[error("{source:?}")]
37    IonError {
38        #[from]
39        source: IonError,
40    },
41}
42
43// io::Error does not implement PartialEq, which precludes us from simply deriving an implementation.
44impl PartialEq for IonSchemaError {
45    fn eq(&self, other: &Self) -> bool {
46        use IonSchemaError::*;
47        match (self, other) {
48            // We can compare the io::Errors' ErrorKinds, offering a weak definition of equality.
49            (IoError { source: s1 }, IoError { source: s2 }) => s1.kind() == s2.kind(),
50            (
51                UnresolvableSchemaError { description: s1 },
52                UnresolvableSchemaError { description: s2 },
53            ) => s1 == s2,
54            (InvalidSchemaError { description: s1 }, InvalidSchemaError { description: s2 }) => {
55                s1 == s2
56            }
57            (IonError { source: s1 }, IonError { source: s2 }) => s1 == s2,
58            _ => false,
59        }
60    }
61}
62
63/// A convenience method for creating an IonSchemaResult containing an IonSchemaError::UnresolvableSchemaError
64/// with the provided description text.
65pub fn unresolvable_schema_error<T, S: AsRef<str>>(description: S) -> IonSchemaResult<T> {
66    Err(IonSchemaError::UnresolvableSchemaError {
67        description: description.as_ref().to_string(),
68    })
69}
70
71/// A convenience method for creating an  IonSchemaError::InvalidSchemaError with the provided operation
72/// text.
73pub fn invalid_schema_error_raw<S: AsRef<str>>(description: S) -> IonSchemaError {
74    IonSchemaError::InvalidSchemaError {
75        description: description.as_ref().to_string(),
76    }
77}
78
79/// A convenience method for creating an IonSchemaResult containing an IonSchemaError::InvalidSchemaError
80/// with the provided description text.
81pub fn invalid_schema_error<T, S: AsRef<str>>(description: S) -> IonSchemaResult<T> {
82    Err(IonSchemaError::InvalidSchemaError {
83        description: description.as_ref().to_string(),
84    })
85}
86
87/// A convenience method for creating an  IonSchemaError::InvalidSchemaError with the provided operation
88/// text.
89pub fn unresolvable_schema_error_raw<S: AsRef<str>>(description: S) -> IonSchemaError {
90    IonSchemaError::UnresolvableSchemaError {
91        description: description.as_ref().to_string(),
92    }
93}
94
95/// A macro that checks some condition required to be valid ISL.
96///
97/// If invalid, returns an InvalidSchemaErr with the given error message.
98#[macro_export]
99macro_rules! isl_require {
100    ($expression:expr => $fmt_string:literal $(, $($tt:tt)*)?) => {
101        if ($expression) {
102            Ok(())
103        } else {
104            Err($crate::result::IonSchemaError::InvalidSchemaError {
105                description: format!($fmt_string),
106            })
107        }
108    };
109}