From 63d85e295bdae7f07ca13a04a5cef707426564a2 Mon Sep 17 00:00:00 2001 From: tu6ge Date: Thu, 16 Feb 2023 14:24:04 +0800 Subject: [PATCH] feat(object): ObjectList Add Item generic refrence #12 --- examples/custom.rs | 14 +-- examples/object_custom.rs | 80 +++++++++++++++ examples/parse_xml.rs | 14 +-- src/file.rs | 9 +- src/object.rs | 198 ++++++++++++++++++++++++++++---------- src/tests/traits.rs | 43 +++------ src/traits.rs | 69 ++++++------- 7 files changed, 291 insertions(+), 136 deletions(-) create mode 100644 examples/object_custom.rs diff --git a/examples/custom.rs b/examples/custom.rs index a4b7779..80e5d60 100644 --- a/examples/custom.rs +++ b/examples/custom.rs @@ -15,10 +15,8 @@ struct MyFile { other: String, } -impl RefineObject for MyFile { - type Error = MyError; - - fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { +impl RefineObject for MyFile { + fn set_key(&mut self, key: &str) -> Result<(), MyError> { self.key = key.to_string(); Ok(()) } @@ -30,14 +28,12 @@ struct MyBucket { files: Vec, } -impl RefineObjectList for MyBucket { - type Error = MyError; - - fn set_name(&mut self, name: &str) -> Result<(), Self::Error> { +impl RefineObjectList for MyBucket { + fn set_name(&mut self, name: &str) -> Result<(), MyError> { self.name = name.to_string(); Ok(()) } - fn set_list(&mut self, list: Vec) -> Result<(), Self::Error> { + fn set_list(&mut self, list: Vec) -> Result<(), MyError> { self.files = list; Ok(()) } diff --git a/examples/object_custom.rs b/examples/object_custom.rs new file mode 100644 index 0000000..1ddc103 --- /dev/null +++ b/examples/object_custom.rs @@ -0,0 +1,80 @@ +use aliyun_oss_client::{ + builder::{ArcPointer, BuilderError}, + config::{InvalidObjectDir, ObjectDir, ObjectPath}, + decode::RefineObject, + object::ObjectList, + BucketName, Client, +}; +use dotenv::dotenv; + +#[derive(Debug)] +enum MyObject { + File(ObjectPath), + Dir(ObjectDir<'static>), +} + +impl RefineObject for MyObject { + fn set_key(&mut self, key: &str) -> Result<(), MyError> { + let res = key.parse::(); + + *self = match res { + Ok(file) => MyObject::File(file), + _ => { + let re = key.parse::(); + MyObject::Dir(re.unwrap()) + } + }; + + Ok(()) + } +} + +struct MyError(String); + +impl From for MyError { + fn from(value: quick_xml::Error) -> Self { + Self(value.to_string()) + } +} + +impl From for MyError { + fn from(value: BuilderError) -> Self { + Self(value.to_string()) + } +} + +impl From for MyError { + fn from(value: std::num::ParseIntError) -> Self { + Self(value.to_string()) + } +} + +impl From for MyError { + fn from(value: InvalidObjectDir) -> Self { + Self(value.to_string()) + } +} + +type MyList = ObjectList; + +#[tokio::main] +async fn main() { + dotenv().ok(); + + let client = Client::from_env().unwrap(); + + let mut list = MyList::default(); + + let init_object = || MyObject::File(ObjectPath::default()); + + let _ = client + .base_object_list( + "xxxxxx".parse::().unwrap(), + [], + &mut list, + init_object, + ) + .await; + + println!("list: {:?}", list.object_list); +} diff --git a/examples/parse_xml.rs b/examples/parse_xml.rs index 256f8fe..97c2321 100644 --- a/examples/parse_xml.rs +++ b/examples/parse_xml.rs @@ -7,10 +7,8 @@ struct MyFile { other: String, } -impl RefineObject for MyFile { - type Error = MyError; - - fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { +impl RefineObject for MyFile { + fn set_key(&mut self, key: &str) -> Result<(), MyError> { self.key = key.to_string(); Ok(()) } @@ -22,14 +20,12 @@ struct MyBucket { files: Vec, } -impl RefineObjectList for MyBucket { - type Error = MyError; - - fn set_name(&mut self, name: &str) -> Result<(), Self::Error> { +impl RefineObjectList for MyBucket { + fn set_name(&mut self, name: &str) -> Result<(), MyError> { self.name = name.to_string(); Ok(()) } - fn set_list(&mut self, list: Vec) -> Result<(), Self::Error> { + fn set_list(&mut self, list: Vec) -> Result<(), MyError> { self.files = list; Ok(()) } diff --git a/src/file.rs b/src/file.rs index 0180618..8b3c828 100644 --- a/src/file.rs +++ b/src/file.rs @@ -79,6 +79,7 @@ use crate::{ bucket::Bucket, builder::{ArcPointer, BuilderError, RequestBuilder}, config::{InvalidObjectPath, ObjectBase, ObjectPath}, + decode::RefineObject, object::{Object, ObjectList}, types::{CanonicalizedResource, ContentRange}, Client, @@ -326,7 +327,9 @@ impl Files for Bucket { } /// 可将 `Object` 实例作为参数传递给各种操作方法 -impl Files for ObjectList { +impl + Send + Sync, E: From + Send + Sync> Files + for ObjectList +{ type Path = Object; type Err = FileError; fn get_url(&self, path: Self::Path) -> Result<(Url, CanonicalizedResource), FileError> { @@ -533,7 +536,9 @@ impl AlignBuilder for Bucket { } } -impl AlignBuilder for ObjectList { +impl + Send + Sync, E: From + Send + Sync> AlignBuilder + for ObjectList +{ #[inline] fn builder_with_header>( &self, diff --git a/src/object.rs b/src/object.rs index 16c472a..04c56ed 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,10 +1,101 @@ +//! # Object 相关功能 +//! `ObjectList` 对应文件列表,`Object` 对应的是单个文件对象 +//! +//! `ObjectList` 也可以支持自定义的类型存储单个文件对象,例如 [issue 12](https://github.com/tu6ge/oss-rs/issues/12) 提到的,有些时候, +//! Oss 接口不仅返回文件路径,还会返回目录路径,可以使用如下例子进行适配 +//! +//! ```rust,no_run +//! use aliyun_oss_client::{ +//! builder::{ArcPointer, BuilderError}, +//! config::{InvalidObjectDir, ObjectDir, ObjectPath}, +//! decode::RefineObject, +//! object::ObjectList, +//! BucketName, Client, +//! }; +//! use dotenv::dotenv; +//! +//! #[derive(Debug)] +//! enum MyObject { +//! File(ObjectPath), +//! Dir(ObjectDir<'static>), +//! } +//! +//! impl RefineObject for MyObject { +//! fn set_key(&mut self, key: &str) -> Result<(), MyError> { +//! let res = key.parse::(); +//! +//! *self = match res { +//! Ok(file) => MyObject::File(file), +//! _ => { +//! let re = key.parse::(); +//! MyObject::Dir(re.unwrap()) +//! } +//! }; +//! +//! Ok(()) +//! } +//! } +//! +//! struct MyError(String); +//! +//! impl From for MyError { +//! fn from(value: quick_xml::Error) -> Self { +//! Self(value.to_string()) +//! } +//! } +//! +//! impl From for MyError { +//! fn from(value: BuilderError) -> Self { +//! Self(value.to_string()) +//! } +//! } +//! +//! impl From for MyError { +//! fn from(value: std::num::ParseIntError) -> Self { +//! Self(value.to_string()) +//! } +//! } +//! +//! impl From for MyError { +//! fn from(value: InvalidObjectDir) -> Self { +//! Self(value.to_string()) +//! } +//! } +//! +//! type MyList = ObjectList; +//! +//! #[tokio::main] +//! async fn main() { +//! dotenv().ok(); +//! +//! let client = Client::from_env().unwrap(); +//! +//! let mut list = MyList::default(); +//! +//! let init_object = || MyObject::File(ObjectPath::default()); +//! +//! let _ = client +//! .base_object_list( +//! "xxxxxx".parse::().unwrap(), +//! [], +//! &mut list, +//! init_object, +//! ) +//! .await; +//! +//! println!("list: {:?}", list.object_list); +//! } +//! ``` + #[cfg(feature = "blocking")] use crate::builder::RcPointer; use crate::builder::{ArcPointer, BuilderError, PointerFamily}; use crate::client::ClientArc; #[cfg(feature = "blocking")] use crate::client::ClientRc; -use crate::config::{BucketBase, CommonPrefixes, ObjectBase, ObjectDir, ObjectPath}; +use crate::config::{ + BucketBase, CommonPrefixes, InvalidObjectDir, ObjectBase, ObjectDir, ObjectPath, +}; use crate::decode::{RefineObject, RefineObjectList}; use crate::errors::{OssError, OssResult}; #[cfg(feature = "blocking")] @@ -21,6 +112,8 @@ use http::Method; use oss_derive::oss_gen_rc; use std::fmt; +use std::marker::PhantomData; +use std::num::ParseIntError; #[cfg(feature = "blocking")] use std::rc::Rc; use std::sync::Arc; @@ -30,19 +123,26 @@ use std::vec::IntoIter; /// TODO impl core::ops::Index #[derive(Clone)] #[non_exhaustive] -pub struct ObjectList { +pub struct ObjectList< + P: PointerFamily = ArcPointer, + Item: RefineObject = Object

, + E: From = OssError, +> { pub(crate) bucket: BucketBase, prefix: String, max_keys: u32, key_count: u64, - pub object_list: Vec>, + pub object_list: Vec, next_continuation_token: Option, common_prefixes: CommonPrefixes, - client: PointerSel::PointerType, + client: P::PointerType, search_query: Query, + ph_err: PhantomData, } -impl fmt::Debug for ObjectList { +impl, E: From> fmt::Debug + for ObjectList +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("ObjectList") .field("bucket", &self.bucket) @@ -57,7 +157,7 @@ impl fmt::Debug for ObjectList { } #[oss_gen_rc] -impl Default for ObjectList { +impl, E: From> Default for ObjectList { fn default() -> Self { Self { bucket: BucketBase::default(), @@ -69,17 +169,18 @@ impl Default for ObjectList { common_prefixes: CommonPrefixes::default(), client: Arc::new(ClientArc::default()), search_query: Query::default(), + ph_err: PhantomData, } } } -impl ObjectList { +impl, E: From> ObjectList { pub fn new>( bucket: BucketBase, prefix: String, max_keys: u32, key_count: u64, - object_list: Vec>, + object_list: Vec, next_continuation_token: Option, client: T::PointerType, search_query: Q, @@ -94,6 +195,7 @@ impl ObjectList { common_prefixes: CommonPrefixes::default(), client, search_query: Query::from_iter(search_query), + ph_err: PhantomData, } } @@ -146,13 +248,13 @@ impl ObjectList { } /// 将 object 列表转化为迭代器 - pub fn object_iter(self) -> IntoIter> { + pub fn object_iter(self) -> IntoIter { self.object_list.into_iter() } } #[oss_gen_rc] -impl ObjectList { +impl, E: From> ObjectList { pub fn set_client(&mut self, client: Arc) { self.client = client; } @@ -162,8 +264,8 @@ impl ObjectList { } } -impl ObjectList { - pub async fn get_next_list(&self) -> OssResult { +impl ObjectList { + pub async fn get_next_list(&self) -> OssResult> { match self.next_query() { None => Err(OssError::WithoutMore), Some(query) => { @@ -265,7 +367,7 @@ impl ObjectList { } } -impl ObjectList { +impl, E: From> ObjectList { #[inline] pub fn set_search_query(&mut self, search_query: Query) { self.search_query = search_query; @@ -473,86 +575,83 @@ impl ObjectBuilder { } } -impl RefineObject for Object { - type Error = OssError; - +impl RefineObject for Object { #[inline] - fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { + fn set_key(&mut self, key: &str) -> Result<(), OssError> { self.base.set_path(key).map_err(OssError::from) } #[inline] - fn set_last_modified(&mut self, value: &str) -> Result<(), Self::Error> { + fn set_last_modified(&mut self, value: &str) -> Result<(), OssError> { self.last_modified = value.parse::>().map_err(OssError::from)?; Ok(()) } #[inline] - fn set_etag(&mut self, value: &str) -> Result<(), Self::Error> { + fn set_etag(&mut self, value: &str) -> Result<(), OssError> { self.etag = value.to_string(); Ok(()) } #[inline] - fn set_type(&mut self, value: &str) -> Result<(), Self::Error> { + fn set_type(&mut self, value: &str) -> Result<(), OssError> { self._type = value.to_string(); Ok(()) } #[inline] - fn set_size(&mut self, size: &str) -> Result<(), Self::Error> { + fn set_size(&mut self, size: &str) -> Result<(), OssError> { self.size = size.parse::().map_err(OssError::from)?; Ok(()) } #[inline] - fn set_storage_class(&mut self, value: &str) -> Result<(), Self::Error> { + fn set_storage_class(&mut self, value: &str) -> Result<(), OssError> { self.storage_class = value.to_string(); Ok(()) } } -impl RefineObjectList> for ObjectList { - type Error = OssError; - +impl, E> RefineObjectList + for ObjectList +where + E: From + From + From, +{ #[inline] - fn set_key_count(&mut self, key_count: &str) -> Result<(), Self::Error> { - self.key_count = key_count.parse::().map_err(OssError::from)?; + fn set_key_count(&mut self, key_count: &str) -> Result<(), E> { + self.key_count = key_count.parse::().map_err(E::from)?; Ok(()) } #[inline] - fn set_prefix(&mut self, prefix: &str) -> Result<(), Self::Error> { + fn set_prefix(&mut self, prefix: &str) -> Result<(), E> { self.prefix = prefix.to_owned(); Ok(()) } #[inline] - fn set_common_prefix( - &mut self, - list: &Vec>, - ) -> Result<(), Self::Error> { + fn set_common_prefix(&mut self, list: &Vec>) -> Result<(), E> { for val in list.iter() { self.common_prefixes - .push(val.parse::().map_err(Self::Error::from)?); + .push(val.parse::().map_err(E::from)?); } Ok(()) } #[inline] - fn set_max_keys(&mut self, max_keys: &str) -> Result<(), Self::Error> { - self.max_keys = max_keys.parse::().map_err(OssError::from)?; + fn set_max_keys(&mut self, max_keys: &str) -> Result<(), E> { + self.max_keys = max_keys.parse::().map_err(E::from)?; Ok(()) } #[inline] - fn set_next_continuation_token(&mut self, token: Option<&str>) -> Result<(), Self::Error> { + fn set_next_continuation_token(&mut self, token: Option<&str>) -> Result<(), E> { self.next_continuation_token = token.map(|t| t.to_owned()); Ok(()) } #[inline] - fn set_list(&mut self, list: Vec>) -> Result<(), Self::Error> { + fn set_list(&mut self, list: Vec) -> Result<(), E> { self.object_list = list; Ok(()) } @@ -617,10 +716,8 @@ impl Client { /// #[allow(dead_code)] /// other: String, /// } - /// impl RefineObject for MyFile { - /// type Error = MyError; - /// - /// fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { + /// impl RefineObject for MyFile { + /// fn set_key(&mut self, key: &str) -> Result<(), MyError> { /// self.key = key.to_string(); /// Ok(()) /// } @@ -632,14 +729,13 @@ impl Client { /// files: Vec, /// } /// - /// impl RefineObjectList for MyBucket { - /// type Error = MyError; + /// impl RefineObjectList for MyBucket { /// - /// fn set_name(&mut self, name: &str) -> Result<(), Self::Error> { + /// fn set_name(&mut self, name: &str) -> Result<(), MyError> { /// self.name = name.to_string(); /// Ok(()) /// } - /// fn set_list(&mut self, list: Vec) -> Result<(), Self::Error> { + /// fn set_list(&mut self, list: Vec) -> Result<(), MyError> { /// self.files = list; /// Ok(()) /// } @@ -697,9 +793,9 @@ impl Client { init_object: F, ) -> Result<(), E> where - List: RefineObjectList, - Item: RefineObject, - E: From + From, + List: RefineObjectList, + Item: RefineObject, + E: From + From, F: FnMut() -> Item, { let query = Query::from_iter(query); @@ -774,9 +870,9 @@ impl ClientRc { init_object: F, ) -> Result<(), E> where - List: RefineObjectList, - Item: RefineObject, - E: From + From, + List: RefineObjectList, + Item: RefineObject, + E: From + From, F: FnMut() -> Item, { let bucket = BucketBase::new(name.into(), self.get_endpoint().to_owned()); diff --git a/src/tests/traits.rs b/src/tests/traits.rs index 8b14f62..20331fe 100644 --- a/src/tests/traits.rs +++ b/src/tests/traits.rs @@ -30,9 +30,8 @@ mod object_list_xml { #[derive(Default)] struct ObjectA {} - impl RefineObject for ObjectA { - type Error = MyError; - fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { + impl RefineObject for ObjectA { + fn set_key(&mut self, key: &str) -> Result<(), MyError> { unsafe { if OBEJCT_ITEM_ID == 0 { assert_eq!(key, "9AB932LY.jpeg"); @@ -44,7 +43,7 @@ mod object_list_xml { } Ok(()) } - fn set_last_modified(&mut self, last_modified: &str) -> Result<(), Self::Error> { + fn set_last_modified(&mut self, last_modified: &str) -> Result<(), MyError> { unsafe { if OBEJCT_ITEM_ID == 0 { assert_eq!(last_modified, "2022-06-26T09:53:21.000Z"); @@ -56,7 +55,7 @@ mod object_list_xml { } Ok(()) } - fn set_etag(&mut self, etag: &str) -> Result<(), Self::Error> { + fn set_etag(&mut self, etag: &str) -> Result<(), MyError> { unsafe { if OBEJCT_ITEM_ID == 0 { assert_eq!(etag, "F75A15996D0857B16FA31A3B16624C26"); @@ -68,7 +67,7 @@ mod object_list_xml { } Ok(()) } - fn set_type(&mut self, _type: &str) -> Result<(), Self::Error> { + fn set_type(&mut self, _type: &str) -> Result<(), MyError> { unsafe { if OBEJCT_ITEM_ID == 0 { assert_eq!(_type, "Normal"); @@ -80,7 +79,7 @@ mod object_list_xml { } Ok(()) } - fn set_size(&mut self, size: &str) -> Result<(), Self::Error> { + fn set_size(&mut self, size: &str) -> Result<(), MyError> { unsafe { if OBEJCT_ITEM_ID == 0 { assert_eq!(size, "18027"); @@ -92,7 +91,7 @@ mod object_list_xml { } Ok(()) } - fn set_storage_class(&mut self, storage_class: &str) -> Result<(), Self::Error> { + fn set_storage_class(&mut self, storage_class: &str) -> Result<(), MyError> { assert_eq!(storage_class, "Standard"); unsafe { OBEJCT_ITEM_ID += 1; @@ -101,28 +100,24 @@ mod object_list_xml { } } struct ListB {} - impl RefineObjectList for ListB { - type Error = MyError; - fn set_name(&mut self, name: &str) -> Result<(), Self::Error> { + impl RefineObjectList for ListB { + fn set_name(&mut self, name: &str) -> Result<(), MyError> { assert_eq!(name, "foo_bucket"); Ok(()) } - fn set_prefix(&mut self, prefix: &str) -> Result<(), Self::Error> { + fn set_prefix(&mut self, prefix: &str) -> Result<(), MyError> { assert_eq!(prefix, ""); Ok(()) } - fn set_max_keys(&mut self, max_keys: &str) -> Result<(), Self::Error> { + fn set_max_keys(&mut self, max_keys: &str) -> Result<(), MyError> { assert_eq!(max_keys, "100"); Ok(()) } - fn set_key_count(&mut self, key_count: &str) -> Result<(), Self::Error> { + fn set_key_count(&mut self, key_count: &str) -> Result<(), MyError> { assert_eq!(key_count, "3"); Ok(()) } - fn set_next_continuation_token( - &mut self, - token: Option<&str>, - ) -> Result<(), Self::Error> { + fn set_next_continuation_token(&mut self, token: Option<&str>) -> Result<(), MyError> { assert!(matches!(token, None)); Ok(()) } @@ -384,17 +379,11 @@ mod object_list_xml { #[derive(Default)] struct ObjectA {} - impl RefineObject for ObjectA { - type Error = MyError; - } + impl RefineObject for ObjectA {} struct ListB {} - impl RefineObjectList for ListB { - type Error = MyError; - fn set_next_continuation_token( - &mut self, - token: Option<&str>, - ) -> Result<(), Self::Error> { + impl RefineObjectList for ListB { + fn set_next_continuation_token(&mut self, token: Option<&str>) -> Result<(), MyError> { assert!( matches!(token, Some(v) if v=="CiphcHBzL1RhdXJpIFB1Ymxpc2ggQXBwXzAuMS42X3g2NF9lbi1VUy5tc2kQAA--") ); diff --git a/src/traits.rs b/src/traits.rs index 7dff5cc..22574dd 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -13,10 +13,9 @@ //! #[allow(dead_code)] //! other: String, //! } -//! impl RefineObject for MyFile { -//! type Error = MyError; +//! impl RefineObject for MyFile { //! -//! fn set_key(&mut self, key: &str) -> Result<(), Self::Error> { +//! fn set_key(&mut self, key: &str) -> Result<(), MyError> { //! self.key = key.to_string(); //! Ok(()) //! } @@ -28,14 +27,13 @@ //! files: Vec, //! } //! -//! impl RefineObjectList for MyBucket { -//! type Error = MyError; +//! impl RefineObjectList for MyBucket { //! -//! fn set_name(&mut self, name: &str) -> Result<(), Self::Error> { +//! fn set_name(&mut self, name: &str) -> Result<(), MyError> { //! self.name = name.to_string(); //! Ok(()) //! } -//! fn set_list(&mut self, list: Vec) -> Result<(), Self::Error> { +//! fn set_list(&mut self, list: Vec) -> Result<(), MyError> { //! self.files = list; //! Ok(()) //! } @@ -96,32 +94,30 @@ use std::borrow::Cow; use quick_xml::{events::Event, Reader}; -pub trait RefineObject { - type Error; - +pub trait RefineObject { /// 提取 key - fn set_key(&mut self, _key: &str) -> Result<(), Self::Error> { + fn set_key(&mut self, _key: &str) -> Result<(), Error> { Ok(()) } /// 提取最后修改时间 - fn set_last_modified(&mut self, _last_modified: &str) -> Result<(), Self::Error> { + fn set_last_modified(&mut self, _last_modified: &str) -> Result<(), Error> { Ok(()) } - fn set_etag(&mut self, _etag: &str) -> Result<(), Self::Error> { + fn set_etag(&mut self, _etag: &str) -> Result<(), Error> { Ok(()) } - fn set_type(&mut self, _type: &str) -> Result<(), Self::Error> { + fn set_type(&mut self, _type: &str) -> Result<(), Error> { Ok(()) } - fn set_size(&mut self, _size: &str) -> Result<(), Self::Error> { + fn set_size(&mut self, _size: &str) -> Result<(), Error> { Ok(()) } - fn set_storage_class(&mut self, _storage_class: &str) -> Result<(), Self::Error> { + fn set_storage_class(&mut self, _storage_class: &str) -> Result<(), Error> { Ok(()) } } @@ -152,49 +148,47 @@ const ID: &[u8] = b"ID"; const DISPLAY_NAME: &[u8] = b"DisplayName"; const CONTENTS: &[u8] = b"Contents"; -pub trait RefineObjectList +pub trait RefineObjectList where - T: RefineObject, - Self::Error: From + From, + T: RefineObject, + Error: From, { - type Error; - /// 提取 bucket 名 - fn set_name(&mut self, _name: &str) -> Result<(), Self::Error> { + fn set_name(&mut self, _name: &str) -> Result<(), Error> { Ok(()) } /// 提取前缀 - fn set_prefix(&mut self, _prefix: &str) -> Result<(), Self::Error> { + fn set_prefix(&mut self, _prefix: &str) -> Result<(), Error> { Ok(()) } /// 提取文件目录 - fn set_common_prefix(&mut self, _list: &Vec>) -> Result<(), Self::Error> { + fn set_common_prefix(&mut self, _list: &Vec>) -> Result<(), Error> { Ok(()) } - fn set_max_keys(&mut self, _max_keys: &str) -> Result<(), Self::Error> { + fn set_max_keys(&mut self, _max_keys: &str) -> Result<(), Error> { Ok(()) } - fn set_key_count(&mut self, _key_count: &str) -> Result<(), Self::Error> { + fn set_key_count(&mut self, _key_count: &str) -> Result<(), Error> { Ok(()) } /// 提取翻页信息,有下一页,返回 Some, 否则返回 None - fn set_next_continuation_token(&mut self, _token: Option<&str>) -> Result<(), Self::Error> { + fn set_next_continuation_token(&mut self, _token: Option<&str>) -> Result<(), Error> { Ok(()) } /// 提取 object 列表 - fn set_list(&mut self, _list: Vec) -> Result<(), Self::Error> { + fn set_list(&mut self, _list: Vec) -> Result<(), Error> { Ok(()) } /// # 由 xml 转 struct 的底层实现 /// - `init_object` 用于初始化 object 结构体的方法 - fn decode(&mut self, xml: &str, mut init_object: F) -> Result<(), Self::Error> + fn decode(&mut self, xml: &str, mut init_object: F) -> Result<(), Error> where F: FnMut() -> T, { @@ -290,7 +284,7 @@ where break; } // exits the loop when reaching end of file Err(e) => { - return Err(Self::Error::from(e)); + return Err(Error::from(e)); } _ => (), // There are several other `Event`s we do not consider here } @@ -489,21 +483,20 @@ mod tests { #[test] fn test_common_prefixes() { struct ObjectA {} - impl RefineObject for ObjectA { - type Error = quick_xml::Error; - } + impl RefineObject for ObjectA {} struct ListA {} - impl RefineObjectList for ListA { - type Error = quick_xml::Error; - - fn set_prefix(&mut self, prefix: &str) -> Result<(), Self::Error> { + impl RefineObjectList for ListA { + fn set_prefix(&mut self, prefix: &str) -> Result<(), quick_xml::Error> { assert!(prefix == "bar"); Ok(()) } - fn set_common_prefix(&mut self, list: &Vec>) -> Result<(), Self::Error> { + fn set_common_prefix( + &mut self, + list: &Vec>, + ) -> Result<(), quick_xml::Error> { assert!(list[0] == "foo1/"); assert!(list[1] == "foo2/"); Ok(())