1
Fork 0

Handle fallout in libserialize

API Changes:

- from_base64() returns Result<Vec<u8>, FromBase64Error>
- from_hex() returns Result<Vec<u8>, FromHexError>
- json::List is a Vec<Json>
- Decodable is no longer implemented on ~[T] (but Encodable still is)
- DecoderHelpers::read_to_vec() returns a Result<Vec<T>, E>
This commit is contained in:
Kevin Ballard 2014-05-03 23:34:26 -07:00
parent 2a0dac6f58
commit cd3f31d9d1
4 changed files with 73 additions and 88 deletions

View file

@ -146,7 +146,7 @@ impl<'a> ToBase64 for &'a [u8] {
} }
unsafe { unsafe {
str::raw::from_utf8_owned(v.move_iter().collect()) str::raw::from_utf8(v.as_slice()).to_owned()
} }
} }
} }
@ -155,7 +155,7 @@ impl<'a> ToBase64 for &'a [u8] {
pub trait FromBase64 { pub trait FromBase64 {
/// Converts the value of `self`, interpreted as base64 encoded data, into /// Converts the value of `self`, interpreted as base64 encoded data, into
/// an owned vector of bytes, returning the vector. /// an owned vector of bytes, returning the vector.
fn from_base64(&self) -> Result<~[u8], FromBase64Error>; fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error>;
} }
/// Errors that can occur when decoding a base64 encoded string /// Errors that can occur when decoding a base64 encoded string
@ -192,14 +192,13 @@ impl<'a> FromBase64 for &'a str {
* ```rust * ```rust
* extern crate serialize; * extern crate serialize;
* use serialize::base64::{ToBase64, FromBase64, STANDARD}; * use serialize::base64::{ToBase64, FromBase64, STANDARD};
* use std::str;
* *
* fn main () { * fn main () {
* let hello_str = bytes!("Hello, World").to_base64(STANDARD); * let hello_str = bytes!("Hello, World").to_base64(STANDARD);
* println!("base64 output: {}", hello_str); * println!("base64 output: {}", hello_str);
* let res = hello_str.from_base64(); * let res = hello_str.from_base64();
* if res.is_ok() { * if res.is_ok() {
* let opt_bytes = str::from_utf8_owned(res.unwrap()); * let opt_bytes = StrBuf::from_utf8(res.unwrap());
* if opt_bytes.is_some() { * if opt_bytes.is_some() {
* println!("decoded from base64: {}", opt_bytes.unwrap()); * println!("decoded from base64: {}", opt_bytes.unwrap());
* } * }
@ -207,7 +206,7 @@ impl<'a> FromBase64 for &'a str {
* } * }
* ``` * ```
*/ */
fn from_base64(&self) -> Result<~[u8], FromBase64Error> { fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
let mut r = Vec::new(); let mut r = Vec::new();
let mut buf: u32 = 0; let mut buf: u32 = 0;
let mut modulus = 0; let mut modulus = 0;
@ -256,7 +255,7 @@ impl<'a> FromBase64 for &'a str {
_ => return Err(InvalidBase64Length), _ => return Err(InvalidBase64Length),
} }
Ok(r.move_iter().collect()) Ok(r)
} }
} }
@ -301,21 +300,21 @@ mod tests {
#[test] #[test]
fn test_from_base64_basic() { fn test_from_base64_basic() {
assert_eq!("".from_base64().unwrap(), "".as_bytes().to_owned()); assert_eq!("".from_base64().unwrap().as_slice(), "".as_bytes());
assert_eq!("Zg==".from_base64().unwrap(), "f".as_bytes().to_owned()); assert_eq!("Zg==".from_base64().unwrap().as_slice(), "f".as_bytes());
assert_eq!("Zm8=".from_base64().unwrap(), "fo".as_bytes().to_owned()); assert_eq!("Zm8=".from_base64().unwrap().as_slice(), "fo".as_bytes());
assert_eq!("Zm9v".from_base64().unwrap(), "foo".as_bytes().to_owned()); assert_eq!("Zm9v".from_base64().unwrap().as_slice(), "foo".as_bytes());
assert_eq!("Zm9vYg==".from_base64().unwrap(), "foob".as_bytes().to_owned()); assert_eq!("Zm9vYg==".from_base64().unwrap().as_slice(), "foob".as_bytes());
assert_eq!("Zm9vYmE=".from_base64().unwrap(), "fooba".as_bytes().to_owned()); assert_eq!("Zm9vYmE=".from_base64().unwrap().as_slice(), "fooba".as_bytes());
assert_eq!("Zm9vYmFy".from_base64().unwrap(), "foobar".as_bytes().to_owned()); assert_eq!("Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
} }
#[test] #[test]
fn test_from_base64_newlines() { fn test_from_base64_newlines() {
assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(), assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap().as_slice(),
"foobar".as_bytes().to_owned()); "foobar".as_bytes());
assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(), assert_eq!("Zm9vYg==\r\n".from_base64().unwrap().as_slice(),
"foob".as_bytes().to_owned()); "foob".as_bytes());
} }
#[test] #[test]
@ -341,8 +340,8 @@ mod tests {
for _ in range(0, 1000) { for _ in range(0, 1000) {
let times = task_rng().gen_range(1u, 100); let times = task_rng().gen_range(1u, 100);
let v = Vec::from_fn(times, |_| random::<u8>()); let v = Vec::from_fn(times, |_| random::<u8>());
assert_eq!(v.as_slice().to_base64(STANDARD).from_base64().unwrap(), assert_eq!(v.as_slice().to_base64(STANDARD).from_base64().unwrap().as_slice(),
v.as_slice().to_owned()); v.as_slice());
} }
} }

View file

@ -45,7 +45,7 @@ impl<'a> ToHex for &'a [u8] {
} }
unsafe { unsafe {
str::raw::from_utf8_owned(v.move_iter().collect()) str::raw::from_utf8(v.as_slice()).to_owned()
} }
} }
} }
@ -54,7 +54,7 @@ impl<'a> ToHex for &'a [u8] {
pub trait FromHex { pub trait FromHex {
/// Converts the value of `self`, interpreted as hexadecimal encoded data, /// Converts the value of `self`, interpreted as hexadecimal encoded data,
/// into an owned vector of bytes, returning the vector. /// into an owned vector of bytes, returning the vector.
fn from_hex(&self) -> Result<~[u8], FromHexError>; fn from_hex(&self) -> Result<Vec<u8>, FromHexError>;
} }
/// Errors that can occur when decoding a hex encoded string /// Errors that can occur when decoding a hex encoded string
@ -91,19 +91,18 @@ impl<'a> FromHex for &'a str {
* ```rust * ```rust
* extern crate serialize; * extern crate serialize;
* use serialize::hex::{FromHex, ToHex}; * use serialize::hex::{FromHex, ToHex};
* use std::str;
* *
* fn main () { * fn main () {
* let hello_str = "Hello, World".as_bytes().to_hex(); * let hello_str = "Hello, World".as_bytes().to_hex();
* println!("{}", hello_str); * println!("{}", hello_str);
* let bytes = hello_str.from_hex().unwrap(); * let bytes = hello_str.from_hex().unwrap();
* println!("{:?}", bytes); * println!("{:?}", bytes);
* let result_str = str::from_utf8_owned(bytes).unwrap(); * let result_str = StrBuf::from_utf8(bytes).unwrap();
* println!("{}", result_str); * println!("{}", result_str);
* } * }
* ``` * ```
*/ */
fn from_hex(&self) -> Result<~[u8], FromHexError> { fn from_hex(&self) -> Result<Vec<u8>, FromHexError> {
// This may be an overestimate if there is any whitespace // This may be an overestimate if there is any whitespace
let mut b = Vec::with_capacity(self.len() / 2); let mut b = Vec::with_capacity(self.len() / 2);
let mut modulus = 0; let mut modulus = 0;
@ -150,10 +149,10 @@ mod tests {
#[test] #[test]
pub fn test_from_hex_okay() { pub fn test_from_hex_okay() {
assert_eq!("666f6f626172".from_hex().unwrap(), assert_eq!("666f6f626172".from_hex().unwrap().as_slice(),
"foobar".as_bytes().to_owned()); "foobar".as_bytes());
assert_eq!("666F6F626172".from_hex().unwrap(), assert_eq!("666F6F626172".from_hex().unwrap().as_slice(),
"foobar".as_bytes().to_owned()); "foobar".as_bytes());
} }
#[test] #[test]
@ -169,8 +168,8 @@ mod tests {
#[test] #[test]
pub fn test_from_hex_ignores_whitespace() { pub fn test_from_hex_ignores_whitespace() {
assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(), assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap().as_slice(),
"foobar".as_bytes().to_owned()); "foobar".as_bytes());
} }
#[test] #[test]
@ -183,8 +182,8 @@ mod tests {
#[test] #[test]
pub fn test_from_hex_all_bytes() { pub fn test_from_hex_all_bytes() {
for i in range(0, 256) { for i in range(0, 256) {
assert_eq!(format!("{:02x}", i as uint).from_hex().unwrap(), ~[i as u8]); assert_eq!(format!("{:02x}", i as uint).from_hex().unwrap().as_slice(), &[i as u8]);
assert_eq!(format!("{:02X}", i as uint).from_hex().unwrap(), ~[i as u8]); assert_eq!(format!("{:02X}", i as uint).from_hex().unwrap().as_slice(), &[i as u8]);
} }
} }

View file

@ -258,7 +258,7 @@ pub enum Json {
Null, Null,
} }
pub type List = ~[Json]; pub type List = Vec<Json>;
pub type Object = TreeMap<~str, Json>; pub type Object = TreeMap<~str, Json>;
/// The errors that can arise while parsing a JSON stream. /// The errors that can arise while parsing a JSON stream.
@ -2211,7 +2211,7 @@ impl<A:ToJson,B:ToJson> ToJson for (A, B) {
fn to_json(&self) -> Json { fn to_json(&self) -> Json {
match *self { match *self {
(ref a, ref b) => { (ref a, ref b) => {
List(box [a.to_json(), b.to_json()]) List(vec![a.to_json(), b.to_json()])
} }
} }
} }
@ -2221,7 +2221,7 @@ impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
fn to_json(&self) -> Json { fn to_json(&self) -> Json {
match *self { match *self {
(ref a, ref b, ref c) => { (ref a, ref b, ref c) => {
List(box [a.to_json(), b.to_json(), c.to_json()]) List(vec![a.to_json(), b.to_json(), c.to_json()])
} }
} }
} }
@ -2298,12 +2298,12 @@ mod tests {
struct Inner { struct Inner {
a: (), a: (),
b: uint, b: uint,
c: ~[~str], c: Vec<~str>,
} }
#[deriving(Eq, Encodable, Decodable, Show)] #[deriving(Eq, Encodable, Decodable, Show)]
struct Outer { struct Outer {
inner: ~[Inner], inner: Vec<Inner>,
} }
fn mk_object(items: &[(~str, Json)]) -> Json { fn mk_object(items: &[(~str, Json)]) -> Json {
@ -2360,22 +2360,22 @@ mod tests {
#[test] #[test]
fn test_write_list() { fn test_write_list() {
assert_eq!(List(~[]).to_str(), "[]".to_owned()); assert_eq!(List(vec![]).to_str(), "[]".to_owned());
assert_eq!(List(~[]).to_pretty_str(), "[]".to_owned()); assert_eq!(List(vec![]).to_pretty_str(), "[]".to_owned());
assert_eq!(List(~[Boolean(true)]).to_str(), "[true]".to_owned()); assert_eq!(List(vec![Boolean(true)]).to_str(), "[true]".to_owned());
assert_eq!( assert_eq!(
List(~[Boolean(true)]).to_pretty_str(), List(vec![Boolean(true)]).to_pretty_str(),
"\ "\
[\n \ [\n \
true\n\ true\n\
]".to_owned() ]".to_owned()
); );
let long_test_list = List(box [ let long_test_list = List(vec![
Boolean(false), Boolean(false),
Null, Null,
List(box [String("foo\nbar".to_owned()), Number(3.5)])]); List(vec![String("foo\nbar".to_owned()), Number(3.5)])]);
assert_eq!(long_test_list.to_str(), assert_eq!(long_test_list.to_str(),
"[false,null,[\"foo\\nbar\",3.5]]".to_owned()); "[false,null,[\"foo\\nbar\",3.5]]".to_owned());
@ -2411,7 +2411,7 @@ mod tests {
); );
let complex_obj = mk_object([ let complex_obj = mk_object([
("b".to_owned(), List(box [ ("b".to_owned(), List(vec![
mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]), mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
mk_object([("d".to_owned(), String("".to_owned()))]) mk_object([("d".to_owned(), String("".to_owned()))])
])) ]))
@ -2443,7 +2443,7 @@ mod tests {
let a = mk_object([ let a = mk_object([
("a".to_owned(), Boolean(true)), ("a".to_owned(), Boolean(true)),
("b".to_owned(), List(box [ ("b".to_owned(), List(vec![
mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]), mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
mk_object([("d".to_owned(), String("".to_owned()))]) mk_object([("d".to_owned(), String("".to_owned()))])
])) ]))
@ -2678,44 +2678,44 @@ mod tests {
assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4)));
assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4)));
assert_eq!(from_str("[]"), Ok(List(~[]))); assert_eq!(from_str("[]"), Ok(List(vec![])));
assert_eq!(from_str("[ ]"), Ok(List(~[]))); assert_eq!(from_str("[ ]"), Ok(List(vec![])));
assert_eq!(from_str("[true]"), Ok(List(~[Boolean(true)]))); assert_eq!(from_str("[true]"), Ok(List(vec![Boolean(true)])));
assert_eq!(from_str("[ false ]"), Ok(List(~[Boolean(false)]))); assert_eq!(from_str("[ false ]"), Ok(List(vec![Boolean(false)])));
assert_eq!(from_str("[null]"), Ok(List(~[Null]))); assert_eq!(from_str("[null]"), Ok(List(vec![Null])));
assert_eq!(from_str("[3, 1]"), assert_eq!(from_str("[3, 1]"),
Ok(List(~[Number(3.0), Number(1.0)]))); Ok(List(vec![Number(3.0), Number(1.0)])));
assert_eq!(from_str("\n[3, 2]\n"), assert_eq!(from_str("\n[3, 2]\n"),
Ok(List(~[Number(3.0), Number(2.0)]))); Ok(List(vec![Number(3.0), Number(2.0)])));
assert_eq!(from_str("[2, [4, 1]]"), assert_eq!(from_str("[2, [4, 1]]"),
Ok(List(~[Number(2.0), List(~[Number(4.0), Number(1.0)])]))); Ok(List(vec![Number(2.0), List(vec![Number(4.0), Number(1.0)])])));
} }
#[test] #[test]
fn test_decode_list() { fn test_decode_list() {
let mut decoder = Decoder::new(from_str("[]").unwrap()); let mut decoder = Decoder::new(from_str("[]").unwrap());
let v: ~[()] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<()> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[]); assert_eq!(v, vec![]);
let mut decoder = Decoder::new(from_str("[null]").unwrap()); let mut decoder = Decoder::new(from_str("[null]").unwrap());
let v: ~[()] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<()> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[()]); assert_eq!(v, vec![()]);
let mut decoder = Decoder::new(from_str("[true]").unwrap()); let mut decoder = Decoder::new(from_str("[true]").unwrap());
let v: ~[bool] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<bool> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[true]); assert_eq!(v, vec![true]);
let mut decoder = Decoder::new(from_str("[true]").unwrap()); let mut decoder = Decoder::new(from_str("[true]").unwrap());
let v: ~[bool] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<bool> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[true]); assert_eq!(v, vec![true]);
let mut decoder = Decoder::new(from_str("[3, 1]").unwrap()); let mut decoder = Decoder::new(from_str("[3, 1]").unwrap());
let v: ~[int] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<int> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[3, 1]); assert_eq!(v, vec![3, 1]);
let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap()); let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap());
let v: ~[~[uint]] = Decodable::decode(&mut decoder).unwrap(); let v: Vec<Vec<uint>> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, ~[~[3], ~[1, 2]]); assert_eq!(v, vec![vec![3], vec![1, 2]]);
} }
#[test] #[test]
@ -2750,7 +2750,7 @@ mod tests {
"{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
mk_object([ mk_object([
("a".to_owned(), Number(1.0)), ("a".to_owned(), Number(1.0)),
("b".to_owned(), List(~[Boolean(true)])) ("b".to_owned(), List(vec![Boolean(true)]))
])); ]));
assert_eq!(from_str( assert_eq!(from_str(
"{".to_owned() + "{".to_owned() +
@ -2763,7 +2763,7 @@ mod tests {
"}").unwrap(), "}").unwrap(),
mk_object([ mk_object([
("a".to_owned(), Number(1.0)), ("a".to_owned(), Number(1.0)),
("b".to_owned(), List(~[ ("b".to_owned(), List(vec![
Boolean(true), Boolean(true),
String("foo\nbar".to_owned()), String("foo\nbar".to_owned()),
mk_object([ mk_object([
@ -2785,8 +2785,8 @@ mod tests {
assert_eq!( assert_eq!(
v, v,
Outer { Outer {
inner: ~[ inner: vec![
Inner { a: (), b: 2, c: ~["abc".to_owned(), "xyz".to_owned()] } Inner { a: (), b: 2, c: vec!["abc".to_owned(), "xyz".to_owned()] }
] ]
} }
); );
@ -2837,7 +2837,7 @@ mod tests {
x: f64, x: f64,
y: bool, y: bool,
z: ~str, z: ~str,
w: ~[DecodeStruct] w: Vec<DecodeStruct>
} }
#[deriving(Decodable)] #[deriving(Decodable)]
enum DecodeEnum { enum DecodeEnum {

View file

@ -451,19 +451,6 @@ impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for ~[T] {
} }
} }
impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for ~[T] {
fn decode(d: &mut D) -> Result<~[T], E> {
d.read_seq(|d, len| {
let mut v: Vec<T> = Vec::with_capacity(len);
for i in range(0, len) {
v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
}
let k = v.move_iter().collect::<~[T]>();
Ok(k)
})
}
}
impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for Vec<T> { impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for Vec<T> {
fn encode(&self, s: &mut S) -> Result<(), E> { fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_seq(self.len(), |s| { s.emit_seq(self.len(), |s| {
@ -557,7 +544,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for path::posix::Path {
impl<E, D: Decoder<E>> Decodable<D, E> for path::posix::Path { impl<E, D: Decoder<E>> Decodable<D, E> for path::posix::Path {
fn decode(d: &mut D) -> Result<path::posix::Path, E> { fn decode(d: &mut D) -> Result<path::posix::Path, E> {
let bytes: ~[u8] = try!(Decodable::decode(d)); let bytes: Vec<u8> = try!(Decodable::decode(d));
Ok(path::posix::Path::new(bytes)) Ok(path::posix::Path::new(bytes))
} }
} }
@ -570,7 +557,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for path::windows::Path {
impl<E, D: Decoder<E>> Decodable<D, E> for path::windows::Path { impl<E, D: Decoder<E>> Decodable<D, E> for path::windows::Path {
fn decode(d: &mut D) -> Result<path::windows::Path, E> { fn decode(d: &mut D) -> Result<path::windows::Path, E> {
let bytes: ~[u8] = try!(Decodable::decode(d)); let bytes: Vec<u8> = try!(Decodable::decode(d));
Ok(path::windows::Path::new(bytes)) Ok(path::windows::Path::new(bytes))
} }
} }
@ -600,17 +587,17 @@ impl<E, S:Encoder<E>> EncoderHelpers<E> for S {
} }
pub trait DecoderHelpers<E> { pub trait DecoderHelpers<E> {
fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<~[T], E>; fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<Vec<T>, E>;
} }
impl<E, D:Decoder<E>> DecoderHelpers<E> for D { impl<E, D:Decoder<E>> DecoderHelpers<E> for D {
fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<~[T], E> { fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<Vec<T>, E> {
self.read_seq(|this, len| { self.read_seq(|this, len| {
let mut v = Vec::with_capacity(len); let mut v = Vec::with_capacity(len);
for i in range(0, len) { for i in range(0, len) {
v.push(try!(this.read_seq_elt(i, |this| f(this)))); v.push(try!(this.read_seq_elt(i, |this| f(this))));
} }
Ok(v.move_iter().collect()) Ok(v)
}) })
} }
} }