Skip to content

Commit fc589cb

Browse files
committed
feat(doit): multi-part mime-type and add_parts()
Next we will implement the actual Read method
1 parent 3ea5e19 commit fc589cb

2 files changed

Lines changed: 26 additions & 11 deletions

File tree

src/mako/lib/mbuild.mako

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ match result {
461461
## "the trait `core::marker::Sized` is not implemented for the type `std::io::Read`"
462462
use hyper::client::IntoBody;
463463
use std::io::{Read, Seek};
464+
use hyper::header::{ContentType, ContentLength};
464465
let mut params: Vec<(&str, String)> = Vec::with_capacity(${len(params) + len(reserved_params)} + ${paddfields}.len());
465466
% if response_schema:
466467
params.push(("alt", "json".to_string()));
@@ -614,14 +615,14 @@ else {
614615
% if request_value and simple_media_param:
615616
let mut request_value_reader = io::Cursor::new(json_encoded_request.clone().into_bytes());
616617
let mut mp_reader: cmn::MultiPartReader = Default::default();
617-
let mut content_type = hyper::header::ContentType(json_mime_type.clone());
618+
let mut content_type = ContentType(json_mime_type.clone());
618619
let mut body_reader: &mut io::Read = match ${simple_media_param.type.arg_name}.as_mut() {
619620
Some(&mut (ref mut reader, size, ref mime)) => {
620621
let rsize = request_value_reader.seek(io::SeekFrom::End(0)).unwrap();
621622
request_value_reader.seek(io::SeekFrom::Start(0)).ok();
622623
mp_reader = mp_reader.add_part(&mut request_value_reader, rsize, &json_mime_type)
623624
.add_part(reader, size, mime);
624-
## TODO: content_type = multi-part
625+
content_type = ContentType(mp_reader.mime_type());
625626
&mut mp_reader
626627
}
627628
None => &mut request_value_reader,
@@ -637,8 +638,8 @@ else {
637638
% if request_value:
638639
% if not simple_media_param:
639640
640-
.header(hyper::header::ContentType(json_mime_type.clone()))
641-
.header(hyper::header::ContentLength(json_encoded_request.len() as u64))
641+
.header(ContentType(json_mime_type.clone()))
642+
.header(ContentLength(json_encoded_request.len() as u64))
642643
.body(json_encoded_request.as_slice())\
643644
% else:
644645
@@ -649,8 +650,8 @@ else {
649650
;
650651
% if simple_media_param and not request_value:
651652
if let Some(&mut (ref mut reader, size, ref mime)) = ${simple_media_param.type.arg_name}.as_mut() {
652-
req = req.header(hyper::header::ContentType(mime.clone()))
653-
.header(hyper::header::ContentLength(size))
653+
req = req.header(ContentType(mime.clone()))
654+
.header(ContentLength(size))
654655
.body(reader.into_body());
655656
}
656657
% endif ## media upload handling

src/rust/cmn.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::marker::MarkerTrait;
22
use std::io::{self, Read, Seek, Cursor};
33

4-
use mime;
4+
use mime::{Mime, TopLevel, SubLevel, Attr, Value};
55
use oauth2;
66
use hyper;
7+
use hyper::header::{ContentType, ContentLength, Headers};
78

89
/// Identifies the Hub. There is only one per library, this trait is supposed
910
/// to make intended use more explicit.
@@ -117,14 +118,15 @@ pub enum Result<T = ()> {
117118
Success(T),
118119
}
119120

121+
const BOUNDARY: &'static str = "MDuXWGyeE33QFXGchb2VFWc4Z7945d";
120122

121123
/// Provides a `Read` interface that converts multiple parts into the protocol
122124
/// identified by [RFC2387](https://tools.ietf.org/html/rfc2387).
123125
/// **Note**: This implementation is just as rich as it needs to be to perform uploads
124126
/// to google APIs, and might not be a fully-featured implementation.
125127
#[derive(Default)]
126128
pub struct MultiPartReader<'a> {
127-
raw_parts: Vec<(hyper::header::Headers, &'a mut Read)>,
129+
raw_parts: Vec<(Headers, &'a mut Read)>,
128130
current_part: Option<(Cursor<Vec<u8>>, &'a mut Read)>,
129131
}
130132

@@ -143,11 +145,23 @@ impl<'a> MultiPartReader<'a> {
143145
/// # Panics
144146
///
145147
/// If this method is called after the first `read` call, it will panic
146-
pub fn add_part(mut self, reader: &'a mut Read, size: u64, mime_type: &mime::Mime) -> MultiPartReader<'a> {
147-
// let mut headers = hyper::header::Headers::
148-
// raw_parts.push((headers, reader));
148+
pub fn add_part(mut self, reader: &'a mut Read, size: u64, mime_type: &Mime) -> MultiPartReader<'a> {
149+
let mut headers = Headers::new();
150+
headers.set(ContentType(mime_type.clone()));
151+
headers.set(ContentLength(size));
152+
self.raw_parts.push((headers, reader));
149153
self
150154
}
155+
156+
/// Returns the mime-type representing our multi-part message.
157+
/// Use it with the ContentType header.
158+
pub fn mime_type(&self) -> Mime {
159+
Mime(
160+
TopLevel::Multipart,
161+
SubLevel::Ext("Related".to_string()),
162+
vec![(Attr::Ext("boundary".to_string()), Value::Ext(BOUNDARY.to_string()))],
163+
)
164+
}
151165
}
152166

153167
impl<'a> Read for MultiPartReader<'a> {

0 commit comments

Comments
 (0)