1use std::borrow::Cow;
98use std::error::Error as StdError;
99use std::fmt::Display;
100use std::num::ParseIntError;
101
102use quick_xml::{events::Event, Reader};
103
104use crate::types::InvalidEndPoint;
105#[cfg(feature = "core")]
106use crate::{
107 errors::OssError,
108 types::object::{InvalidObjectDir, InvalidObjectPath},
109};
110
111#[cfg(test)]
112mod test;
113
114const PREFIX: &[u8] = b"Prefix";
115const COMMON_PREFIX: &[u8] = b"CommonPrefixes";
116const NAME: &[u8] = b"Name";
117const MAX_KEYS: &[u8] = b"MaxKeys";
118const KEY_COUNT: &[u8] = b"KeyCount";
119const IS_TRUNCATED: &[u8] = b"IsTruncated";
120const NEXT_CONTINUATION_TOKEN: &[u8] = b"NextContinuationToken";
121const KEY: &[u8] = b"Key";
122const LAST_MODIFIED: &[u8] = b"LastModified";
123const E_TAG: &[u8] = b"ETag";
124const TYPE: &[u8] = b"Type";
125const SIZE: &[u8] = b"Size";
126const STORAGE_CLASS: &[u8] = b"StorageClass";
127const BUCKET: &[u8] = b"Bucket";
128
129const CREATION_DATE: &[u8] = b"CreationDate";
130const EXTRANET_ENDPOINT: &[u8] = b"ExtranetEndpoint";
131const INTRANET_ENDPOINT: &[u8] = b"IntranetEndpoint";
132const LOCATION: &[u8] = b"Location";
133
134const MARKER: &[u8] = b"Marker";
135const NEXT_MARKER: &[u8] = b"NextMarker";
136const ID: &[u8] = b"ID";
137const DISPLAY_NAME: &[u8] = b"DisplayName";
138const CONTENTS: &[u8] = b"Contents";
139
140const TRUE: &str = "true";
141
142pub trait RefineObject<Error: StdError + 'static> {
144 fn set_key(&mut self, _key: &str) -> Result<(), Error> {
146 Ok(())
147 }
148
149 fn set_last_modified(&mut self, _last_modified: &str) -> Result<(), Error> {
151 Ok(())
152 }
153
154 fn set_etag(&mut self, _etag: &str) -> Result<(), Error> {
156 Ok(())
157 }
158
159 fn set_type(&mut self, _type: &str) -> Result<(), Error> {
161 Ok(())
162 }
163
164 fn set_size(&mut self, _size: &str) -> Result<(), Error> {
166 Ok(())
167 }
168
169 fn set_storage_class(&mut self, _storage_class: &str) -> Result<(), Error> {
171 Ok(())
172 }
173
174 fn decode(&mut self, xml: &str) -> Result<(), InnerItemError> {
176 let mut reader = Reader::from_str(xml);
177 let mut buf = Vec::with_capacity(xml.len());
178 loop {
179 match reader.read_event_into(&mut buf) {
180 Ok(Event::Start(e)) => match e.name().as_ref() {
181 KEY => self.set_key(&reader.read_text(e.to_end().name())?)?,
182 LAST_MODIFIED => {
183 self.set_last_modified(&reader.read_text(e.to_end().name())?)?
184 }
185 E_TAG => {
186 let tag = reader.read_text(e.to_end().name())?;
187 self.set_etag(tag.trim_matches('"'))?;
188 }
189 TYPE => self.set_type(&reader.read_text(e.to_end().name())?)?,
190 SIZE => {
191 self.set_size(&reader.read_text(e.to_end().name())?)?;
192 }
193 STORAGE_CLASS => {
194 self.set_storage_class(&reader.read_text(e.to_end().name())?)?;
195 }
196 _ => (),
197 },
198 Ok(Event::Eof) => {
199 break;
200 } Err(e) => {
202 return Err(InnerItemError::from(e));
203 }
204 _ => (), }
206 buf.clear();
207 }
208 Ok(())
209 }
210}
211
212pub trait RefineObjectList<T, Error, ItemErr = Error>
214where
215 T: RefineObject<ItemErr>,
216 Error: ListError,
217 ItemErr: StdError + 'static,
218{
219 fn set_name(&mut self, _name: &str) -> Result<(), Error> {
221 Ok(())
222 }
223
224 fn set_prefix(&mut self, _prefix: &str) -> Result<(), Error> {
226 Ok(())
227 }
228
229 fn set_common_prefix(&mut self, _list: &[Cow<'_, str>]) -> Result<(), Error> {
231 Ok(())
232 }
233
234 fn set_max_keys(&mut self, _max_keys: &str) -> Result<(), Error> {
236 Ok(())
237 }
238
239 fn set_key_count(&mut self, _key_count: &str) -> Result<(), Error> {
241 Ok(())
242 }
243
244 fn set_next_continuation_token_str(&mut self, _token: &str) -> Result<(), Error> {
246 Ok(())
247 }
248
249 fn set_list(&mut self, _list: Vec<T>) -> Result<(), Error> {
251 Ok(())
252 }
253
254 fn decode_common_prefix(&mut self, xml: &str) -> Result<(), InnerListError> {
256 let mut reader = Reader::from_str(xml);
257 let mut buf = Vec::with_capacity(xml.len());
258 let mut prefix_vec = Vec::new();
259
260 loop {
261 match reader.read_event_into(&mut buf) {
262 Ok(Event::Start(e)) => {
263 if e.name().as_ref() == PREFIX {
264 prefix_vec.push(reader.read_text(e.to_end().name())?);
265 }
266 }
267 Ok(Event::Eof) => {
268 break;
269 } Err(e) => {
271 return Err(InnerListError::from(e));
272 }
273 _ => (), }
275 buf.clear();
276 }
277 self.set_common_prefix(&prefix_vec)?;
278
279 Ok(())
280 }
281
282 fn decode<F>(&mut self, xml: &str, init_object: F) -> Result<(), InnerListError>
285 where
286 F: for<'a> Fn(&'a mut Self) -> Option<T>,
287 {
288 let mut result = Vec::new();
290 let mut reader = Reader::from_str(xml);
291 reader.trim_text(true);
292 let mut buf = Vec::with_capacity(xml.len());
293
294 loop {
295 match reader.read_event_into(&mut buf) {
296 Ok(Event::Start(e)) => {
297 match e.name().as_ref() {
298 COMMON_PREFIX => {
299 self.decode_common_prefix(&reader.read_text(e.to_end().name())?)?;
300 }
301 PREFIX => {
302 self.set_prefix(&reader.read_text(e.to_end().name())?)?;
303 }
304 NAME => self.set_name(&reader.read_text(e.to_end().name())?)?,
305 MAX_KEYS => self.set_max_keys(&reader.read_text(e.to_end().name())?)?,
306 KEY_COUNT => self.set_key_count(&reader.read_text(e.to_end().name())?)?,
307 IS_TRUNCATED => {
308 }
310 NEXT_CONTINUATION_TOKEN => {
311 self.set_next_continuation_token_str(
312 &reader.read_text(e.to_end().name())?,
313 )?;
314 }
315 CONTENTS => {
316 let mut object =
318 init_object(self).ok_or(InnerListError::init_error(true))?;
319 object.decode(&reader.read_text(e.to_end().name())?)?;
320 result.push(object);
321 }
322 _ => (),
323 }
324 }
325 Ok(Event::Eof) => {
326 self.set_list(result)?;
327 break;
328 } Err(e) => {
330 return Err(InnerListError::from(e));
331 }
332 _ => (), }
334 buf.clear();
335 }
336
337 Ok(())
338 }
339}
340
341pub trait RefineBucket<Error: StdError + 'static> {
343 fn set_name(&mut self, _name: &str) -> Result<(), Error> {
345 Ok(())
346 }
347
348 fn set_creation_date(&mut self, _creation_date: &str) -> Result<(), Error> {
350 Ok(())
351 }
352
353 fn set_location(&mut self, _location: &str) -> Result<(), Error> {
355 Ok(())
356 }
357
358 fn set_extranet_endpoint(&mut self, _extranet_endpoint: &str) -> Result<(), Error> {
360 Ok(())
361 }
362
363 fn set_intranet_endpoint(&mut self, _intranet_endpoint: &str) -> Result<(), Error> {
365 Ok(())
366 }
367
368 fn set_storage_class(&mut self, _storage_class: &str) -> Result<(), Error> {
370 Ok(())
371 }
372
373 fn decode(&mut self, xml: &str) -> Result<(), InnerItemError> {
375 let mut reader = Reader::from_str(xml);
377 reader.trim_text(true);
378 let mut buf = Vec::with_capacity(xml.len());
379
380 loop {
381 match reader.read_event_into(&mut buf) {
382 Ok(Event::Start(e)) => match e.name().as_ref() {
383 NAME => self.set_name(&reader.read_text(e.to_end().name())?)?,
384 CREATION_DATE => {
385 self.set_creation_date(&reader.read_text(e.to_end().name())?)?
386 }
387 EXTRANET_ENDPOINT => {
388 self.set_extranet_endpoint(&reader.read_text(e.to_end().name())?)?
389 }
390 INTRANET_ENDPOINT => {
391 self.set_intranet_endpoint(&reader.read_text(e.to_end().name())?)?
392 }
393 LOCATION => self.set_location(&reader.read_text(e.to_end().name())?)?,
394 STORAGE_CLASS => {
395 self.set_storage_class(&reader.read_text(e.to_end().name())?)?
396 }
397 _ => (),
398 },
399 Ok(Event::Eof) => {
400 break;
401 } Err(e) => {
403 return Err(InnerItemError::from(e));
404 }
405 _ => (), }
407 buf.clear();
408 }
409 Ok(())
410 }
411}
412
413pub trait RefineBucketList<T: RefineBucket<ItemErr>, Error, ItemErr = Error>
415where
416 Error: ListError,
417 ItemErr: StdError + 'static,
418{
419 fn set_prefix(&mut self, _prefix: &str) -> Result<(), Error> {
421 Ok(())
422 }
423
424 fn set_marker(&mut self, _marker: &str) -> Result<(), Error> {
426 Ok(())
427 }
428
429 fn set_max_keys(&mut self, _max_keys: &str) -> Result<(), Error> {
431 Ok(())
432 }
433
434 fn set_is_truncated(&mut self, _is_truncated: bool) -> Result<(), Error> {
436 Ok(())
437 }
438
439 fn set_next_marker(&mut self, _next_marker: &str) -> Result<(), Error> {
441 Ok(())
442 }
443
444 fn set_id(&mut self, _id: &str) -> Result<(), Error> {
446 Ok(())
447 }
448
449 fn set_display_name(&mut self, _display_name: &str) -> Result<(), Error> {
451 Ok(())
452 }
453
454 fn set_list(&mut self, _list: Vec<T>) -> Result<(), Error> {
456 Ok(())
457 }
458
459 fn decode<F>(&mut self, xml: &str, init_bucket: F) -> Result<(), InnerListError>
461 where
462 F: for<'a> Fn(&'a mut Self) -> Option<T>,
463 {
464 let mut result = Vec::new();
465 let mut reader = Reader::from_str(xml);
466 reader.trim_text(true);
467 let mut buf = Vec::with_capacity(xml.len());
468
469 loop {
470 match reader.read_event_into(&mut buf) {
471 Ok(Event::Start(e)) => match e.name().as_ref() {
472 PREFIX => self.set_prefix(&reader.read_text(e.to_end().name())?)?,
473 MARKER => self.set_marker(&reader.read_text(e.to_end().name())?)?,
474 MAX_KEYS => self.set_max_keys(&reader.read_text(e.to_end().name())?)?,
475 IS_TRUNCATED => {
476 self.set_is_truncated(reader.read_text(e.to_end().name())? == TRUE)?;
477 }
478 NEXT_MARKER => self.set_next_marker(&reader.read_text(e.to_end().name())?)?,
479 ID => self.set_id(&reader.read_text(e.to_end().name())?)?,
480 DISPLAY_NAME => self.set_display_name(&reader.read_text(e.to_end().name())?)?,
481 BUCKET => {
482 let mut bucket =
484 init_bucket(self).ok_or(InnerListError::init_error(false))?;
485 bucket.decode(&reader.read_text(e.to_end().name())?)?;
486 result.push(bucket);
487 }
488 _ => (),
489 },
490 Ok(Event::Eof) => {
491 self.set_list(result)?;
492 break;
493 } Err(e) => {
495 return Err(InnerListError::from(e));
496 }
497 _ => (), }
499 buf.clear();
500 }
501 Ok(())
502 }
503}
504
505#[derive(Debug)]
511#[doc(hidden)]
512#[non_exhaustive]
513pub struct InnerItemError(Box<dyn StdError + 'static>);
514
515impl<T: StdError + 'static> From<T> for InnerItemError {
516 fn from(err: T) -> Self {
517 Self(Box::new(err))
518 }
519}
520
521impl Display for InnerItemError {
522 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
523 write!(fmt, "{}", self.0)
524 }
525}
526
527impl InnerItemError {
528 #[cfg(test)]
529 pub(crate) fn new() -> Self {
530 #[derive(Debug)]
531 struct MyError;
532 impl Display for MyError {
533 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
534 "demo".fmt(f)
535 }
536 }
537 impl StdError for MyError {}
538
539 Self(Box::new(MyError {}))
540 }
541
542 pub fn get_source(&self) -> Option<&(dyn StdError + 'static)> {
543 Some(self.0.as_ref())
544 }
545}
546
547pub trait ListError: StdError + 'static {}
551
552impl ListError for ParseIntError {}
553
554impl ListError for InvalidEndPoint {}
555
556#[cfg(feature = "core")]
557impl ListError for InvalidObjectPath {}
558#[cfg(feature = "core")]
559impl ListError for InvalidObjectDir {}
560#[cfg(feature = "core")]
561impl ListError for chrono::ParseError {}
562#[cfg(feature = "core")]
563impl ListError for OssError {}
564
565impl<T: ListError> From<T> for InnerListError {
566 fn from(err: T) -> InnerListError {
567 Self {
568 kind: ListErrorKind::Custom(Box::new(err)),
569 }
570 }
571}
572
573#[derive(Debug)]
579#[non_exhaustive]
580pub struct InnerListError {
581 kind: ListErrorKind,
582}
583
584impl Display for InnerListError {
585 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
586 use ListErrorKind::*;
587 match &self.kind {
588 Item(item) => write!(fmt, "{}", item.0),
589 Xml(xml) => write!(fmt, "{xml}"),
590 Custom(out) => write!(fmt, "{out}"),
591 InitItemFailed(is_object) => {
592 if *is_object {
593 write!(fmt, "init_object failed")
594 } else {
595 write!(fmt, "init_bucket failed")
596 }
597 }
598 }
599 }
600}
601
602impl InnerListError {
603 #[cfg(test)]
604 #[allow(dead_code)]
605 pub(crate) fn from_xml() -> Self {
606 Self {
607 kind: ListErrorKind::Xml(Box::new(quick_xml::Error::TextNotFound)),
608 }
609 }
610
611 fn init_error(is_object: bool) -> Self {
618 Self {
619 kind: ListErrorKind::InitItemFailed(is_object),
620 }
621 }
622
623 #[cfg(test)]
624 #[allow(dead_code)]
625 pub(crate) fn from_custom() -> Self {
626 #[derive(Debug)]
627 struct MyError;
628 impl Display for MyError {
629 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
630 "custom".fmt(f)
631 }
632 }
633 impl StdError for MyError {}
634 Self {
635 kind: ListErrorKind::Custom(Box::new(MyError {})),
636 }
637 }
638
639 pub fn get_source(&self) -> Option<&(dyn StdError + 'static)> {
641 use ListErrorKind::*;
642 match &self.kind {
643 Item(item) => item.get_source(),
644 Xml(xml) => Some(xml),
645 Custom(out) => Some(out.as_ref()),
646 InitItemFailed(_) => None,
647 }
648 }
649}
650
651impl From<InnerItemError> for InnerListError {
652 fn from(value: InnerItemError) -> Self {
653 Self {
654 kind: ListErrorKind::Item(value),
655 }
656 }
657}
658
659impl From<quick_xml::Error> for InnerListError {
660 fn from(value: quick_xml::Error) -> Self {
661 Self {
662 kind: ListErrorKind::Xml(Box::new(value)),
663 }
664 }
665}
666
667#[doc(hidden)]
668#[derive(Debug)]
669#[non_exhaustive]
670enum ListErrorKind {
671 #[non_exhaustive]
672 Item(InnerItemError),
673
674 #[non_exhaustive]
675 Xml(Box<quick_xml::Error>),
676
677 #[non_exhaustive]
678 Custom(Box<dyn StdError + 'static>),
679
680 InitItemFailed(bool),
681}