Skip to content

Commit e3ef866

Browse files
committed
refactor(http): allow MemSlice to be sliced to make copies
1 parent cfcbd8c commit e3ef866

File tree

1 file changed

+85
-17
lines changed

1 file changed

+85
-17
lines changed

src/http/buf.rs

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::cell::UnsafeCell;
22
use std::fmt;
33
use std::io::{self, Read};
4+
use std::ops::{Deref, Range, RangeFrom, RangeTo, RangeFull};
45
use std::ptr;
56
use std::sync::Arc;
67

@@ -189,30 +190,20 @@ impl MemSlice {
189190
end: 0,
190191
}
191192
}
192-
}
193-
194193

195-
#[cfg(test)]
196-
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
197-
fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
198-
let mut v = vec![0; len];
199-
let n = try!(self.read(v.as_mut_slice()));
200-
v.truncate(n);
201-
Ok(MemSlice {
202-
buf: Arc::new(UnsafeCell::new(v)),
203-
start: 0,
204-
end: n,
205-
})
194+
pub fn slice<S: Slice>(&self, range: S) -> MemSlice {
195+
range.slice(self)
206196
}
207197
}
208198

199+
209200
impl fmt::Debug for MemSlice {
210201
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
211202
fmt::Debug::fmt(&**self, f)
212203
}
213204
}
214205

215-
impl ::std::ops::Deref for MemSlice {
206+
impl Deref for MemSlice {
216207
type Target = [u8];
217208
fn deref(&self) -> &[u8] {
218209
unsafe {
@@ -221,15 +212,92 @@ impl ::std::ops::Deref for MemSlice {
221212
}
222213
}
223214

215+
pub trait Slice {
216+
fn slice(self, subject: &MemSlice) -> MemSlice;
217+
}
218+
219+
220+
impl Slice for Range<usize> {
221+
fn slice(self, subject: &MemSlice) -> MemSlice {
222+
assert!(subject.start + self.start <= subject.end);
223+
assert!(subject.start + self.end <= subject.end);
224+
MemSlice {
225+
buf: subject.buf.clone(),
226+
start: subject.start + self.start,
227+
end: subject.start + self.end,
228+
}
229+
}
230+
}
231+
232+
impl Slice for RangeFrom<usize> {
233+
fn slice(self, subject: &MemSlice) -> MemSlice {
234+
assert!(subject.start + self.start <= subject.end);
235+
MemSlice {
236+
buf: subject.buf.clone(),
237+
start: subject.start + self.start,
238+
end: subject.end,
239+
}
240+
}
241+
}
242+
243+
impl Slice for RangeTo<usize> {
244+
fn slice(self, subject: &MemSlice) -> MemSlice {
245+
assert!(subject.start + self.end <= subject.end);
246+
MemSlice {
247+
buf: subject.buf.clone(),
248+
start: subject.start,
249+
end: subject.start + self.end,
250+
}
251+
}
252+
}
253+
254+
impl Slice for RangeFull {
255+
fn slice(self, subject: &MemSlice) -> MemSlice {
256+
MemSlice {
257+
buf: subject.buf.clone(),
258+
start: subject.start,
259+
end: subject.end,
260+
}
261+
}
262+
}
263+
224264
unsafe impl Send for MemBuf {}
225265
unsafe impl Send for MemSlice {}
226266

227-
/*
267+
#[cfg(test)]
268+
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
269+
fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
270+
let mut v = vec![0; len];
271+
let n = try!(self.read(v.as_mut_slice()));
272+
v.truncate(n);
273+
Ok(MemSlice {
274+
buf: Arc::new(UnsafeCell::new(v)),
275+
start: 0,
276+
end: n,
277+
})
278+
}
279+
}
280+
228281
#[cfg(test)]
229282
mod tests {
230283
use super::{MemBuf};
231284

232285
#[test]
233-
fn test_
286+
fn test_mem_slice_slice() {
287+
let mut buf = MemBuf::with_capacity(32);
288+
buf.read_from(&mut &b"Hello World"[..]).unwrap();
289+
290+
let len = buf.len();
291+
let full = buf.slice(len);
292+
293+
assert_eq!(&*full, b"Hello World");
294+
assert_eq!(&*full.slice(6..), b"World");
295+
assert_eq!(&*full.slice(..5), b"Hello");
296+
assert_eq!(&*full.slice(..), b"Hello World");
297+
for a in 0..len {
298+
for b in a..len {
299+
assert_eq!(&*full.slice(a..b), &b"Hello World"[a..b], "{}..{}", a, b);
300+
}
301+
}
302+
}
234303
}
235-
*/

0 commit comments

Comments
 (0)