API cleanups.

This commit is contained in:
Gav Wood 2016-01-08 11:43:11 +01:00
parent 20017b8589
commit f0da76df7c

View File

@ -319,43 +319,68 @@ pub trait Populatable {
/// Copies a bunch of bytes `d` to `self`, overwriting as necessary. /// Copies a bunch of bytes `d` to `self`, overwriting as necessary.
/// ///
/// If `d` is smaller, zero-out the remaining bytes. /// If `d` is smaller, zero-out the remaining bytes.
fn populate_raw(&mut self, d: &[u8]); fn populate_raw(&mut self, d: &[u8]) {
let mut s = self.as_slice_mut();
for i in 0..s.len() {
s[i] = if i < d.len() {d[i]} else {0};
}
}
/// Copies a bunch of bytes `d` to `self`, overwriting as necessary. /// Copies a bunch of bytes `d` to `self`, overwriting as necessary.
/// ///
/// If `d` is smaller, will leave some bytes untouched. /// If `d` is smaller, will leave some bytes untouched.
fn copy_from_raw(&mut self, d: &[u8]); fn fax_raw(&mut self, d: &[u8]) {
use std::io::Write;
self.as_slice_mut().write(&d).unwrap();
}
/// Copies a bunch of bytes `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, will leave some bytes untouched.
fn fax_right_raw(&mut self, d: &[u8]) {
use std::io::Write;
self.as_slice_mut().write(&d).unwrap();
}
/// Copies the raw representation of an object `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, zero-out the remaining bytes.
fn populate_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); }
/// Copies the raw representation of an object `d` to `self`, overwriting as necessary.
///
/// If `d` is smaller, will leave some bytes untouched.
fn fax_raw_from(&mut self, d: &BytesConvertable) { self.populate_raw(d.as_slice()); }
/// Get the raw slice for this object.
fn as_slice_mut(&mut self) -> &mut [u8];
} }
impl<T> Populatable for T where T: Sized { impl<T> Populatable for T where T: Sized {
fn populate_raw(&mut self, d: &[u8]) { fn as_slice_mut(&mut self) -> &mut [u8] {
use std::mem; use std::mem;
use std::slice;
unsafe {
let mut s = slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::<T>());
for i in 0..s.len() {
s[i] = if i < d.len() {d[i]} else {0};
}
};
}
fn copy_from_raw(&mut self, d: &[u8]) {
use std::mem;
use std::io::Write;
unsafe { unsafe {
slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::<T>()) slice::from_raw_parts_mut(self as *mut T as *mut u8, mem::size_of::<T>())
}.write(&d).unwrap(); }
} }
} }
//impl<T: Sized> Populatable for slice<T> {} impl<T> Populatable for [T] where T: Sized {
fn as_slice_mut(&mut self) -> &mut [u8] {
use std::mem;
unsafe {
slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, mem::size_of::<T>() * self.len())
}
}
}
#[test] #[test]
fn copy_from_raw() { fn fax_raw() {
let mut x = [255u8; 4]; let mut x = [255u8; 4];
x.copy_from_raw(&[1u8; 2][..]); x.fax_raw(&[1u8; 2][..]);
assert_eq!(x, [1u8, 1, 255, 255]); assert_eq!(x, [1u8, 1, 255, 255]);
x.copy_from_raw(&[1u8; 6][..]); let mut x = [255u8; 4];
x.fax_raw(&[1u8; 6][..]);
assert_eq!(x, [1u8, 1, 1, 1]); assert_eq!(x, [1u8, 1, 1, 1]);
} }
@ -364,6 +389,27 @@ fn populate_raw() {
let mut x = [255u8; 4]; let mut x = [255u8; 4];
x.populate_raw(&[1u8; 2][..]); x.populate_raw(&[1u8; 2][..]);
assert_eq!(x, [1u8, 1, 0, 0]); assert_eq!(x, [1u8, 1, 0, 0]);
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 6][..]); x.populate_raw(&[1u8; 6][..]);
assert_eq!(x, [1u8, 1, 1, 1]); assert_eq!(x, [1u8, 1, 1, 1]);
} }
#[test]
fn populate_raw_dyn() {
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 2][..]);
assert_eq!(&x[..], [1u8, 1, 0, 0]);
let mut x = [255u8; 4];
x.populate_raw(&[1u8; 6][..]);
assert_eq!(&x[..], [1u8, 1, 1, 1]);
}
#[test]
fn fax_raw_dyn() {
let mut x = [255u8; 4];
x.fax_raw(&[1u8; 2][..]);
assert_eq!(&x[..], [1u8, 1, 255, 255]);
let mut x = [255u8; 4];
x.fax_raw(&[1u8; 6][..]);
assert_eq!(&x[..], [1u8, 1, 1, 1]);
}