1use std::pin::Pin;
2
3use bytes::{Bytes, BytesMut};
4use futures_core::Stream;
5use futures_util::StreamExt;
6use std::result::Result;
7
8use crate::{signer::sha256_hash, utils::EMPTY_CONTENT_SHA256};
9
10#[allow(unused)]
12pub(crate) enum PayloadHash {
13 Checksum(String),
15 Unsigned,
17 Streaming,
19 StreamingTrailer,
22 EmptySha256,
23}
24
25impl PayloadHash {
26 pub fn checksum(hash: String) -> Self {
27 Self::Checksum(hash)
28 }
29
30 pub fn as_str(&self) -> &str {
31 match self {
32 PayloadHash::Checksum(v) => v.as_str(),
33 PayloadHash::EmptySha256 => EMPTY_CONTENT_SHA256,
34 PayloadHash::Unsigned => "UNSIGNED-PAYLOAD",
35 PayloadHash::Streaming => "STREAMING-AWS4-HMAC-SHA256-PAYLOAD",
36 PayloadHash::StreamingTrailer => "STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER",
37 }
38 }
39}
40
41pub enum Data<E> {
43 Bytes(Bytes),
45 Stream(
47 Pin<Box<dyn Stream<Item = Result<Bytes, E>> + Sync + Send>>,
48 usize,
49 ),
50}
51
52impl<E> Data<E> {
53 #[inline]
55 pub fn empty() -> Self {
56 Self::Bytes(Bytes::new())
57 }
58
59 pub async fn convert(self) -> Result<Self, E> {
61 Ok(match self {
62 Data::Stream(mut s, l) => {
63 let mut buf = BytesMut::with_capacity(l);
64 while let Some(data) = s.next().await {
65 buf.extend_from_slice(&data?);
66 }
67 Data::Bytes(buf.freeze())
68 }
69 _ => self,
70 })
71 }
72
73 #[inline]
74 pub fn len(&self) -> usize {
75 match self {
76 Data::Bytes(data) => data.len(),
77 Data::Stream(_, len) => len.clone(),
78 }
79 }
80
81 pub(crate) fn payload_hash(&self) -> PayloadHash {
82 match self {
83 Data::Stream(_, _) => PayloadHash::Streaming,
84 Data::Bytes(data) if data.len() == 0 => PayloadHash::EmptySha256,
85 Data::Bytes(data) => PayloadHash::checksum(sha256_hash(data)),
86 }
87 }
88}
89
90impl<E> Default for Data<E> {
91 fn default() -> Self {
92 Self::empty()
93 }
94}
95
96impl<E> From<Option<Bytes>> for Data<E> {
97 fn from(value: Option<Bytes>) -> Self {
98 match value {
99 Some(v) => Self::Bytes(v),
100 None => Self::empty(),
101 }
102 }
103}
104
105impl<E> From<Bytes> for Data<E> {
106 fn from(value: Bytes) -> Self {
107 Self::Bytes(value)
108 }
109}
110
111impl<E> From<String> for Data<E> {
112 fn from(value: String) -> Self {
113 Self::Bytes(value.into())
114 }
115}
116
117impl<E> From<&'static str> for Data<E> {
118 fn from(value: &'static str) -> Self {
119 Self::Bytes(value.into())
120 }
121}
122
123impl<E> From<Vec<u8>> for Data<E> {
124 fn from(value: Vec<u8>) -> Self {
125 Self::Bytes(value.into())
126 }
127}
128
129impl<E>
130 From<(
131 Pin<Box<dyn Stream<Item = Result<Bytes, E>> + Sync + Send>>,
132 usize,
133 )> for Data<E>
134{
135 fn from(
136 value: (
137 Pin<Box<dyn Stream<Item = Result<Bytes, E>> + Sync + Send>>,
138 usize,
139 ),
140 ) -> Self {
141 Self::Stream(value.0, value.1)
142 }
143}