2017-01-25 18:51:41 +01:00
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
2016-02-09 12:27:05 +01:00
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
2016-05-28 19:30:31 +02:00
//! Serializable wrapper around vector of bytes
2017-02-13 16:38:47 +01:00
use std ::fmt ;
2016-02-08 10:58:08 +01:00
use rustc_serialize ::hex ::ToHex ;
2017-02-13 16:38:47 +01:00
use serde ::{ Serialize , Serializer , Deserialize , Deserializer } ;
use serde ::de ::{ Error , Visitor } ;
2016-03-04 18:10:07 +01:00
use util ::common ::FromHex ;
2016-02-08 10:58:08 +01:00
/// Wrapper structure around vector of bytes.
2016-05-24 21:56:32 +02:00
#[ derive(Debug, PartialEq, Eq, Default, Hash, Clone) ]
2016-03-26 01:15:27 +01:00
pub struct Bytes ( pub Vec < u8 > ) ;
2016-02-08 10:58:08 +01:00
impl Bytes {
/// Simple constructor.
pub fn new ( bytes : Vec < u8 > ) -> Bytes {
Bytes ( bytes )
}
2016-05-28 19:30:31 +02:00
/// Convert back to vector
2017-01-13 09:51:36 +01:00
pub fn into_vec ( self ) -> Vec < u8 > {
2016-05-28 19:30:31 +02:00
self . 0
}
2016-02-08 10:58:08 +01:00
}
2016-06-06 00:24:21 +02:00
impl From < Vec < u8 > > for Bytes {
fn from ( bytes : Vec < u8 > ) -> Bytes {
Bytes ( bytes )
}
}
2016-07-06 11:23:29 +02:00
impl Into < Vec < u8 > > for Bytes {
fn into ( self ) -> Vec < u8 > {
self . 0
}
}
2016-02-08 10:58:08 +01:00
impl Serialize for Bytes {
2017-02-13 16:38:47 +01:00
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
2016-02-08 10:58:08 +01:00
where S : Serializer {
let mut serialized = " 0x " . to_owned ( ) ;
serialized . push_str ( self . 0. to_hex ( ) . as_ref ( ) ) ;
2016-02-27 13:14:58 +01:00
serializer . serialize_str ( serialized . as_ref ( ) )
2016-02-08 10:58:08 +01:00
}
}
2016-03-04 18:10:07 +01:00
impl Deserialize for Bytes {
2017-02-13 16:38:47 +01:00
fn deserialize < D > ( deserializer : D ) -> Result < Bytes , D ::Error >
2016-03-04 18:10:07 +01:00
where D : Deserializer {
deserializer . deserialize ( BytesVisitor )
}
}
struct BytesVisitor ;
impl Visitor for BytesVisitor {
type Value = Bytes ;
2017-02-13 16:38:47 +01:00
fn expecting ( & self , formatter : & mut fmt ::Formatter ) -> fmt ::Result {
write! ( formatter , " a 0x-prefixed, hex-encoded vector of bytes " )
}
fn visit_str < E > ( self , value : & str ) -> Result < Self ::Value , E > where E : Error {
2016-09-26 15:55:44 +02:00
if value . is_empty ( ) {
warn! (
target : " deprecated " ,
" Deserializing empty string as empty bytes. This is a non-standard behaviour that will be removed in future versions. Please update your code to send `0x` instead! "
) ;
Ok ( Bytes ::new ( Vec ::new ( ) ) )
} else if value . len ( ) > = 2 & & & value [ 0 .. 2 ] = = " 0x " & & value . len ( ) & 1 = = 0 {
2016-12-27 12:53:56 +01:00
Ok ( Bytes ::new ( FromHex ::from_hex ( & value [ 2 .. ] ) . map_err ( | _ | Error ::custom ( " invalid hex " ) ) ? ) )
2016-03-04 18:10:07 +01:00
} else {
2016-09-27 11:26:23 +02:00
Err ( Error ::custom ( " invalid format " ) )
2016-03-04 18:10:07 +01:00
}
}
2017-02-13 16:38:47 +01:00
fn visit_string < E > ( self , value : String ) -> Result < Self ::Value , E > where E : Error {
2016-03-04 18:10:07 +01:00
self . visit_str ( value . as_ref ( ) )
}
}
2016-02-08 10:58:08 +01:00
#[ cfg(test) ]
mod tests {
use super ::* ;
use serde_json ;
use rustc_serialize ::hex ::FromHex ;
#[ test ]
fn test_bytes_serialize ( ) {
let bytes = Bytes ( " 0123456789abcdef " . from_hex ( ) . unwrap ( ) ) ;
let serialized = serde_json ::to_string ( & bytes ) . unwrap ( ) ;
assert_eq! ( serialized , r # ""0x0123456789abcdef""# ) ;
}
2016-09-22 14:50:00 +02:00
#[ test ]
fn test_bytes_deserialize ( ) {
2016-09-26 15:55:44 +02:00
// TODO [ToDr] Uncomment when Mist starts sending correct data
// let bytes1: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""""#);
2016-09-22 14:50:00 +02:00
let bytes2 : Result < Bytes , serde_json ::Error > = serde_json ::from_str ( r # ""0x123""# ) ;
2016-09-27 11:26:23 +02:00
let bytes3 : Result < Bytes , serde_json ::Error > = serde_json ::from_str ( r # ""0xgg""# ) ;
2016-09-22 14:50:00 +02:00
2016-09-27 11:26:23 +02:00
let bytes4 : Bytes = serde_json ::from_str ( r # ""0x""# ) . unwrap ( ) ;
let bytes5 : Bytes = serde_json ::from_str ( r # ""0x12""# ) . unwrap ( ) ;
let bytes6 : Bytes = serde_json ::from_str ( r # ""0x0123""# ) . unwrap ( ) ;
2016-09-22 14:50:00 +02:00
2016-09-26 15:55:44 +02:00
// assert!(bytes1.is_err());
2016-09-22 14:50:00 +02:00
assert! ( bytes2 . is_err ( ) ) ;
2016-09-27 11:26:23 +02:00
assert! ( bytes3 . is_err ( ) ) ;
assert_eq! ( bytes4 , Bytes ( vec! [ ] ) ) ;
assert_eq! ( bytes5 , Bytes ( vec! [ 0x12 ] ) ) ;
assert_eq! ( bytes6 , Bytes ( vec! [ 0x1 , 0x23 ] ) ) ;
2016-09-22 14:50:00 +02:00
}
2016-09-26 15:55:44 +02:00
// TODO [ToDr] Remove when Mist starts sending correct data
#[ test ]
fn test_bytes_lenient_against_the_spec_deserialize_for_empty_string_for_mist_compatibility ( ) {
let deserialized : Bytes = serde_json ::from_str ( r # """"# ) . unwrap ( ) ;
assert_eq! ( deserialized , Bytes ( Vec ::new ( ) ) ) ;
}
2016-02-08 10:58:08 +01:00
}