1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use jsonschema::ValidationError;
use std::borrow::Cow;
use thiserror::Error;
use url::Url;

/// Crate-specific error type.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
    /// Cannot resolve schemas with a json-schema scheme.
    #[error("cannot resolve json-schema scheme: {0}")]
    CannotResolveJsonSchemaScheme(Url),

    /// The `stac_extensions` vector, or its contents, are not the correct type.
    #[error("incorrect stac extensions type")]
    IncorrectStacExtensionsType(serde_json::Value),

    /// The url is not a valid file path.
    #[error("invalid file path: {0}")]
    InvalidFilePath(Url),

    /// We cannot handle this url scheme.
    #[error("invalid url scheme: {0}")]
    InvalidUrlScheme(Url),

    /// [reqwest::Error]
    #[error(transparent)]
    Reqwest(#[from] reqwest::Error),

    /// [serde_json::Error]
    #[error(transparent)]
    SerdeJson(#[from] serde_json::Error),

    /// [stac::Error]
    #[error(transparent)]
    Stac(#[from] stac::Error),

    /// A list of validation errors.
    ///
    /// Since we usually don't have the original [serde_json::Value] (because we
    /// create them from the STAC objects), we need these errors to be `'static`
    /// lifetime.
    #[error("validation errors")]
    Validation(Vec<ValidationError<'static>>),

    /// [jsonschema::ValidationError]
    #[error(transparent)]
    JSONSchemaValidation(#[from] ValidationError<'static>),
}

impl Error {
    /// Creates an [crate::Error] from an iterator over [jsonschema::ValidationError].
    #[allow(single_use_lifetimes)]
    pub fn from_validation_errors<'a>(errors: impl Iterator<Item = ValidationError<'a>>) -> Error {
        let mut error_vec = Vec::new();
        for error in errors {
            // Cribbed from https://docs.rs/jsonschema/latest/src/jsonschema/error.rs.html#21-30
            error_vec.push(ValidationError {
                instance_path: error.instance_path.clone(),
                instance: Cow::Owned(error.instance.into_owned()),
                kind: error.kind,
                schema_path: error.schema_path,
            })
        }
        Error::Validation(error_vec)
    }

    /// Creates an [crate::Error] from a single [jsonschema::ValidationError].
    pub fn from_validation_error(error: ValidationError<'_>) -> Error {
        // Cribbed from https://docs.rs/jsonschema/latest/src/jsonschema/error.rs.html#21-30
        Error::JSONSchemaValidation(ValidationError {
            instance_path: error.instance_path.clone(),
            instance: Cow::Owned(error.instance.into_owned()),
            kind: error.kind,
            schema_path: error.schema_path,
        })
    }
}