Skip to content
This repository was archived by the owner on Oct 6, 2020. It is now read-only.

Commit d510304

Browse files
authored
Merge pull request #46 from MindFlavor/feature/get_block_list
Implemented get_block_list with tests
2 parents 6cadcb9 + 5390a06 commit d510304

13 files changed

+463
-129
lines changed

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "azure_sdk_for_rust"
3-
version = "0.7.2"
3+
version = "0.8.0"
44
description = "Rust wrappers around Microsoft Azure REST APIs"
55
readme = "README.md"
66
authors = ["Francesco Cogno <francesco.cogno@outlook.com>", "Max Gortman <mgortman@microsoft.com>", "Dong Liu <doliu@microsoft.com>"]
@@ -28,12 +28,12 @@ quick-error = "1.2.2"
2828
serde = "1.0.66"
2929
serde_derive = "1.0.66"
3030
serde_json = "1.0.19"
31+
serde-xml-rs = "0.2.1"
3132
time = "0.1.40"
3233
tokio-core = "0.1.17"
3334
url = "1.7.0"
34-
uuid = "0.6.5"
35+
uuid = { version = "0.6", features = ["v4"] }
3536
rust-crypto = "0.2.36"
36-
failure = "0.1.1"
3737
smallvec = { version = "0.6", features = ["serde"] }
3838

3939
[features]

examples/put_block_list.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ use azure_sdk_for_rust::{
1717
storage::blob::{Blob, BlobType, PUT_BLOCK_OPTIONS_DEFAULT}, storage::client::Client,
1818
};
1919

20-
use azure_sdk_for_rust::storage::blob::{put_block_list, BlobBlockType, BlockList};
20+
use azure_sdk_for_rust::storage::blob::{
21+
get_block_list, put_block_list, BlobBlockType, BlockList, BlockListType,
22+
};
2123

2224
use hyper::mime::Mime;
2325

@@ -131,14 +133,28 @@ fn code() -> Result<(), Box<Error>> {
131133
});
132134

133135
let block_list = core.run(future)?;
136+
println!("computed block list == {:?}", block_list);
137+
138+
let future = get_block_list(
139+
&client,
140+
&(&container_name as &str, name),
141+
&BlockListType::All,
142+
None,
143+
None,
144+
None,
145+
None,
146+
);
147+
148+
let received_block_list = core.run(future)?;
149+
println!("current block list: {:?}", received_block_list);
134150

135151
// now we can finalize the blob with put_block_list
136152
let future = put_block_list(
137153
&client,
138154
&(&container_name as &str, name),
139155
None,
140156
None,
141-
&block_list,
157+
&received_block_list.block_list.into(),
142158
).map(|_| {
143159
println!("blob finalized!");
144160
});

src/azure/core/errors.rs

+6-22
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use hyper;
88
use hyper::StatusCode;
99
use native_tls;
1010
use serde_json;
11+
use serde_xml_rs;
1112
use std;
1213
use std::io::Error as IOError;
1314
use std::num;
@@ -165,6 +166,11 @@ quick_error! {
165166
display("Native TLS error: {}", err)
166167
cause(err)
167168
}
169+
SerdeXMLDeserializationError(err:serde_xml_rs::Error) {
170+
from()
171+
display("XML deserialization error: {}", err)
172+
cause(err)
173+
}
168174
}
169175
}
170176

@@ -198,10 +204,6 @@ quick_error! {
198204
from()
199205
display("Parsing error: {:?}", err)
200206
}
201-
BlockListParseError(err: BlockListParseError){
202-
from()
203-
display("Block list XML parsing error: {:?}", err)
204-
}
205207
}
206208
}
207209

@@ -211,24 +213,6 @@ impl From<()> for AzureError {
211213
}
212214
}
213215

214-
#[derive(Debug, Fail)]
215-
pub enum BlockListParseError {
216-
#[fail(display = "invalid BlockList XML")]
217-
InvalidBlockListXML,
218-
#[fail(display = "Invalid Block type: {}", name)]
219-
InvalidBlockType { name: String },
220-
#[fail(display = "Token not found: {}", token)]
221-
TokemNotFound { token: String },
222-
#[fail(display = "Gneric parse error")]
223-
GenericParseError,
224-
}
225-
226-
impl std::convert::From<std::option::NoneError> for BlockListParseError {
227-
fn from(_: std::option::NoneError) -> Self {
228-
BlockListParseError::GenericParseError
229-
}
230-
}
231-
232216
#[inline]
233217
pub fn extract_status_headers_and_body(
234218
resp: hyper::client::FutureResponse,

src/azure/core/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ define_encode_set! {
1919
'+', '-', '&'
2020
}
2121
}
22+
23+
use uuid::Uuid;
24+
pub type RequestId = Uuid;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use azure::storage::blob::BlobBlockType;
2+
use std::borrow::Borrow;
3+
4+
#[derive(Debug, Clone, PartialEq)]
5+
pub struct BlobBlockWithSize<T>
6+
where
7+
T: Borrow<str>,
8+
{
9+
pub block_list_type: BlobBlockType<T>,
10+
pub size_in_bytes: u64,
11+
}

src/azure/storage/blob/block_list.rs

+17-93
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use azure::core::errors::BlockListParseError;
2-
use azure::storage::blob::BlobBlockType;
1+
use azure::storage::blob::{BlobBlockType, BlockWithSizeList};
32
use std::borrow::Borrow;
4-
use std::convert::TryFrom;
53

64
#[derive(Default, Debug, Clone, PartialEq)]
75
pub struct BlockList<T>
@@ -11,67 +9,6 @@ where
119
pub blocks: Vec<BlobBlockType<T>>,
1210
}
1311

14-
impl<'a> TryFrom<&'a str> for BlockList<&'a str> {
15-
type Error = BlockListParseError;
16-
17-
fn try_from(xml: &'a str) -> Result<Self, Self::Error> {
18-
// this is terrible XML parsing but will do temporarily.
19-
// at least we are not copying strings around.
20-
// we assume here the XML is composed by
21-
// single byte chars. It should (base64 encoding should
22-
// comply) but if we get unpleasant errors
23-
// this can be a place to start looking
24-
trace!("BlockList::try_from called with xml == \"{}\"", xml);
25-
26-
let mut bl = BlockList { blocks: Vec::new() };
27-
28-
let begin = xml[..].find("<BlockList>")? + "<BlockList>".len();
29-
let end = xml[begin..].find("</BlockList>")? + begin;
30-
31-
debug!("begin == {}, end == {}", begin, end);
32-
33-
let mut cur = begin;
34-
35-
while cur < end {
36-
debug!("cur == {}", cur);
37-
38-
let tagbegin = xml[cur..].find('<')? + cur + 1;
39-
let tagend = xml[cur..].find('>')? + cur;
40-
41-
debug!("tagbegin == {}, tagend == {}", tagbegin, tagend);
42-
let node_type = &xml[tagbegin..tagend];
43-
44-
debug!("{}", node_type);
45-
if node_type == "/BlockList" {
46-
break;
47-
}
48-
49-
cur = tagend + 1;
50-
51-
let close_tag = format!("</{}>", node_type);
52-
let close_pos = xml[cur..].find(&close_tag)? + cur;
53-
54-
let id = &xml[cur..close_pos];
55-
debug!("id == {}", id);
56-
57-
cur = close_pos + close_tag.len() + 1;
58-
59-
bl.blocks.push(match node_type {
60-
"Committed" => BlobBlockType::Committed(id),
61-
"Uncommitted" => BlobBlockType::Uncommitted(id),
62-
"Latest" => BlobBlockType::Latest(id),
63-
_ => {
64-
return Err(BlockListParseError::InvalidBlockType {
65-
name: node_type.to_owned(),
66-
})
67-
}
68-
});
69-
}
70-
71-
Ok(bl)
72-
}
73-
}
74-
7512
impl<'a> BlockList<&'a str> {
7613
pub fn to_owned(&self) -> BlockList<String> {
7714
let mut bl: BlockList<String> = BlockList {
@@ -90,6 +27,19 @@ impl<'a> BlockList<&'a str> {
9027
}
9128
}
9229

30+
impl<T> From<BlockWithSizeList<T>> for BlockList<T>
31+
where
32+
T: Borrow<str> + Default,
33+
{
34+
fn from(b: BlockWithSizeList<T>) -> BlockList<T> {
35+
let mut bl = BlockList::default();
36+
for block in b.blocks {
37+
bl.blocks.push(block.block_list_type);
38+
}
39+
bl
40+
}
41+
}
42+
9343
impl<T> BlockList<T>
9444
where
9545
T: Borrow<str>,
@@ -123,42 +73,16 @@ mod test {
12373
use super::*;
12474

12575
#[test]
126-
fn try_parse() {
127-
let range = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
128-
<BlockList>
129-
<Committed>numero1</Committed>
130-
<Uncommitted>numero2</Uncommitted>
131-
<Uncommitted>numero3</Uncommitted>
132-
<Latest>numero4</Latest>
133-
</BlockList>";
134-
135-
let bl = BlockList::try_from(range).unwrap();
136-
assert!(bl.blocks.len() == 4);
137-
assert!(bl.blocks[0] == BlobBlockType::Committed("numero1"));
138-
assert!(bl.blocks[1] == BlobBlockType::Uncommitted("numero2"));
139-
assert!(bl.blocks[2] == BlobBlockType::Uncommitted("numero3"));
140-
assert!(bl.blocks[3] == BlobBlockType::Latest("numero4"));
141-
}
142-
143-
#[test]
144-
fn to_xml_and_then_parse() {
76+
fn to_xml() {
14577
let mut blocks = BlockList { blocks: Vec::new() };
14678
blocks.blocks.push(BlobBlockType::Committed("numero1"));
14779
blocks.blocks.push(BlobBlockType::Uncommitted("numero2"));
14880
blocks.blocks.push(BlobBlockType::Uncommitted("numero3"));
14981
blocks.blocks.push(BlobBlockType::Latest("numero4"));
15082

151-
let retu: &str = &blocks.to_xml();
152-
153-
let bl2 = BlockList::try_from(retu).unwrap();
154-
assert!(bl2.blocks.len() == 4);
155-
assert!(blocks == bl2);
83+
let _retu: &str = &blocks.to_xml();
15684

157-
let bl_owned = bl2.to_owned();
158-
assert!(bl_owned.blocks[0] == BlobBlockType::Committed(String::from("numero1")));
159-
assert!(bl_owned.blocks[1] == BlobBlockType::Uncommitted(String::from("numero2")));
160-
assert!(bl_owned.blocks[2] == BlobBlockType::Uncommitted(String::from("numero3")));
161-
assert!(bl_owned.blocks[3] == BlobBlockType::Latest(String::from("numero4")));
85+
// to assert with handcrafted XML
16286
}
16387

16488
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub enum BlockListType {
2+
Committed,
3+
Uncommitted,
4+
All,
5+
}

0 commit comments

Comments
 (0)