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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

use http0::header::{InvalidHeaderName, InvalidHeaderValue};
use http0::uri::InvalidUri;
use std::error::Error;
use std::fmt;

#[derive(Debug)]
enum SigningErrorKind {
    FailedToCreateCanonicalRequest { source: CanonicalRequestError },
    UnsupportedIdentityType,
}

/// Error signing request
#[derive(Debug)]
pub struct SigningError {
    kind: SigningErrorKind,
}

impl SigningError {
    pub(crate) fn unsupported_identity_type() -> Self {
        Self {
            kind: SigningErrorKind::UnsupportedIdentityType,
        }
    }
}

impl fmt::Display for SigningError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.kind {
            SigningErrorKind::FailedToCreateCanonicalRequest { .. } => {
                write!(f, "failed to create canonical request")
            }
            SigningErrorKind::UnsupportedIdentityType => {
                write!(f, "only 'AWS credentials' are supported for signing")
            }
        }
    }
}

impl Error for SigningError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.kind {
            SigningErrorKind::FailedToCreateCanonicalRequest { source } => Some(source),
            SigningErrorKind::UnsupportedIdentityType => None,
        }
    }
}

impl From<CanonicalRequestError> for SigningError {
    fn from(source: CanonicalRequestError) -> Self {
        Self {
            kind: SigningErrorKind::FailedToCreateCanonicalRequest { source },
        }
    }
}

#[derive(Debug)]
enum CanonicalRequestErrorKind {
    InvalidHeaderName { source: InvalidHeaderName },
    InvalidHeaderValue { source: InvalidHeaderValue },
    InvalidUri { source: InvalidUri },
    UnsupportedIdentityType,
}

#[derive(Debug)]
pub(crate) struct CanonicalRequestError {
    kind: CanonicalRequestErrorKind,
}

impl fmt::Display for CanonicalRequestError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use CanonicalRequestErrorKind::*;
        match self.kind {
            InvalidHeaderName { .. } => write!(f, "invalid header name"),
            InvalidHeaderValue { .. } => write!(f, "invalid header value"),
            InvalidUri { .. } => write!(f, "the uri was invalid"),
            UnsupportedIdentityType => {
                write!(f, "only AWS credentials are supported for signing")
            }
        }
    }
}

impl Error for CanonicalRequestError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use CanonicalRequestErrorKind::*;
        match &self.kind {
            InvalidHeaderName { source } => Some(source),
            InvalidHeaderValue { source } => Some(source),
            InvalidUri { source } => Some(source),
            UnsupportedIdentityType => None,
        }
    }
}

impl CanonicalRequestError {
    pub(crate) fn unsupported_identity_type() -> Self {
        Self {
            kind: CanonicalRequestErrorKind::UnsupportedIdentityType,
        }
    }
}

impl From<InvalidHeaderName> for CanonicalRequestError {
    fn from(source: InvalidHeaderName) -> Self {
        Self {
            kind: CanonicalRequestErrorKind::InvalidHeaderName { source },
        }
    }
}

impl From<InvalidHeaderValue> for CanonicalRequestError {
    fn from(source: InvalidHeaderValue) -> Self {
        Self {
            kind: CanonicalRequestErrorKind::InvalidHeaderValue { source },
        }
    }
}

impl From<InvalidUri> for CanonicalRequestError {
    fn from(source: InvalidUri) -> Self {
        Self {
            kind: CanonicalRequestErrorKind::InvalidUri { source },
        }
    }
}