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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! Core components for signing API requests.
//!
//! This crate provides the foundational types and traits for the reqsign ecosystem.
//! It defines the core abstractions that enable flexible and extensible request signing.
//!
//! ## Overview
//!
//! The crate is built around several key concepts:
//!
//! - **Context**: A container that holds implementations for file reading, HTTP sending, and environment access
//! - **Traits**: Abstract interfaces for credential loading (`ProvideCredential`) and request signing (`SignRequest`)
//! - **Signer**: The main orchestrator that coordinates credential loading and request signing
//!
//! ## Example
//!
//! ```no_run
//! use reqsign_core::{Context, OsEnv, ProvideCredential, Result, SignRequest, Signer, SigningCredential};
//! use http::request::Parts;
//! use std::time::Duration;
//!
//! // Define your credential type
//! #[derive(Clone, Debug)]
//! struct MyCredential {
//! key: String,
//! secret: String,
//! }
//!
//! impl SigningCredential for MyCredential {
//! fn is_valid(&self) -> bool {
//! !self.key.is_empty() && !self.secret.is_empty()
//! }
//! }
//!
//! // Implement credential loader
//! #[derive(Debug)]
//! struct MyLoader;
//!
//! impl ProvideCredential for MyLoader {
//! type Credential = MyCredential;
//!
//! async fn provide_credential(&self, _: &Context) -> Result<Option<Self::Credential>> {
//! Ok(Some(MyCredential {
//! key: "my-access-key".to_string(),
//! secret: "my-secret-key".to_string(),
//! }))
//! }
//! }
//!
//! // Implement request builder
//! #[derive(Debug)]
//! struct MyBuilder;
//!
//! impl SignRequest for MyBuilder {
//! type Credential = MyCredential;
//!
//! async fn sign_request(
//! &self,
//! _ctx: &Context,
//! req: &mut Parts,
//! _cred: Option<&Self::Credential>,
//! _expires_in: Option<Duration>,
//! ) -> Result<()> {
//! // Add example header
//! req.headers.insert("x-custom-auth", "signed".parse()?);
//! Ok(())
//! }
//! }
//!
//! # async fn example() -> Result<()> {
//! # use reqsign_core::{FileRead, HttpSend};
//! # use bytes::Bytes;
//! #
//! # // Mock implementations for the example
//! # #[derive(Debug, Clone)]
//! # struct MockFileRead;
//! # impl FileRead for MockFileRead {
//! # async fn file_read(&self, _path: &str) -> Result<Vec<u8>> {
//! # Ok(vec![])
//! # }
//! # }
//! #
//! # #[derive(Debug, Clone)]
//! # struct MockHttpSend;
//! # impl HttpSend for MockHttpSend {
//! # async fn http_send(&self, _req: http::Request<Bytes>) -> Result<http::Response<Bytes>> {
//! # Ok(http::Response::builder().status(200).body(Bytes::new())?)
//! # }
//! # }
//! #
//! // Create a context with your implementations
//! let ctx = Context::new()
//! .with_file_read(MockFileRead)
//! .with_http_send(MockHttpSend)
//! .with_env(OsEnv);
//!
//! // Create a signer
//! let signer = Signer::new(ctx, MyLoader, MyBuilder);
//!
//! // Sign your requests
//! let mut parts = http::Request::builder()
//! .method("GET")
//! .uri("https://example.com")
//! .body(())
//! .unwrap()
//! .into_parts()
//! .0;
//!
//! signer.sign(&mut parts, None).await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Traits
//!
//! This crate defines several important traits:
//!
//! - [`FileRead`]: For asynchronous file reading
//! - [`HttpSend`]: For sending HTTP requests
//! - [`Env`]: For environment variable access
//! - [`ProvideCredential`]: For loading credentials from various sources
//! - [`SignRequest`]: For building service-specific signing requests
//! - [`SigningCredential`]: For validating credentials
//!
//! ## Utilities
//!
//! The crate also provides utility modules:
//!
//! - [`hash`]: Cryptographic hashing utilities
//! - [`time`]: Time manipulation utilities
//! - [`utils`]: General utilities including data redaction
// Make sure all our public APIs have docs.
/// Error types for reqsign operations
pub use ;
pub use BoxedFuture;
pub use MaybeSend;
pub use CommandExecute;
pub use CommandExecuteDyn;
pub use CommandOutput;
pub use Context;
pub use Env;
pub use FileRead;
pub use FileReadDyn;
pub use HttpSend;
pub use HttpSendDyn;
pub use NoopCommandExecute;
pub use NoopEnv;
pub use NoopFileRead;
pub use NoopHttpSend;
pub use OsEnv;
pub use StaticEnv;
pub use ProvideCredential;
pub use ProvideCredentialChain;
pub use ProvideCredentialDyn;
pub use SignRequest;
pub use SignRequestDyn;
pub use SigningCredential;
pub use ;
pub use Signer;