nv_redfish_core/
upload.rs1use core::pin::Pin;
17use std::error::Error as StdError;
18use std::fmt;
19use std::time::Duration;
20
21use futures_io::AsyncRead;
22
23const OEM_PREFIX: &str = "Oem";
24
25pub trait UploadReader: AsyncRead + Send + 'static {}
27
28impl<T> UploadReader for T where T: AsyncRead + Send + 'static {}
29
30pub struct DataStream<R> {
32 pub name: String,
34
35 pub reader: R,
37
38 pub content_length: Option<u64>,
40}
41
42impl<R> DataStream<R> {
43 #[must_use]
45 pub fn new(name: impl Into<String>, reader: R) -> Self {
46 Self {
47 name: name.into(),
48 reader,
49 content_length: None,
50 }
51 }
52
53 #[must_use]
55 pub const fn with_content_length(mut self, content_length: u64) -> Self {
56 self.content_length = Some(content_length);
57 self
58 }
59}
60
61#[cfg(feature = "update-service-deprecated")]
63pub struct UploadStream<R> {
64 pub reader: R,
66
67 pub content_length: Option<u64>,
69}
70
71#[cfg(feature = "update-service-deprecated")]
72impl<R> UploadStream<R> {
73 #[must_use]
75 pub const fn new(reader: R) -> Self {
76 Self {
77 reader,
78 content_length: None,
79 }
80 }
81
82 #[must_use]
84 pub const fn with_content_length(mut self, content_length: u64) -> Self {
85 self.content_length = Some(content_length);
86 self
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
92pub struct OemMultipartPartNameError {
93 pub name: String,
95}
96
97impl fmt::Display for OemMultipartPartNameError {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(
100 f,
101 "OEM multipart part name must start with Oem: {}",
102 self.name
103 )
104 }
105}
106
107impl StdError for OemMultipartPartNameError {}
108
109pub type OemMultipartPartReader = Pin<Box<dyn AsyncRead + Send + 'static>>;
111
112pub struct OemMultipartPart {
114 pub name: String,
116
117 pub reader: OemMultipartPartReader,
119
120 pub content_type: Option<String>,
122
123 pub content_length: Option<u64>,
125}
126
127impl OemMultipartPart {
128 #[must_use]
130 pub fn is_name_valid(&self) -> bool {
131 self.name.starts_with(OEM_PREFIX)
132 }
133}
134
135impl OemMultipartPart {
136 pub fn new(
142 name: impl Into<String>,
143 reader: impl UploadReader,
144 ) -> Result<Self, OemMultipartPartNameError> {
145 let name = name.into();
146
147 if !name.starts_with(OEM_PREFIX) {
148 return Err(OemMultipartPartNameError { name });
149 }
150
151 Ok(Self {
152 name,
153 reader: Box::pin(reader),
154 content_type: None,
155 content_length: None,
156 })
157 }
158
159 #[must_use]
161 pub fn with_content_type(mut self, content_type: impl Into<String>) -> Self {
162 self.content_type = Some(content_type.into());
163 self
164 }
165
166 #[must_use]
168 pub const fn with_content_length(mut self, content_length: u64) -> Self {
169 self.content_length = Some(content_length);
170 self
171 }
172}
173
174pub struct MultipartUpdateRequest<'a, U, V> {
176 pub update_parameters: &'a V,
178
179 pub update_stream: DataStream<U>,
181
182 pub oem_parts: Vec<OemMultipartPart>,
184
185 pub upload_timeout: Duration,
187}
188
189#[cfg(feature = "update-service-deprecated")]
191pub struct HttpPushUriUpdateRequest<U> {
192 pub update_stream: UploadStream<U>,
194
195 pub upload_timeout: Duration,
197}