use std::fmt::{self, Debug, Formatter};
pub use structured_data::StructuredData;
pub use immutable_data::ImmutableData;
pub use plain_data::PlainData;
use xor_name::XorName;
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Clone, RustcEncodable, RustcDecodable)]
pub enum Data {
Structured(StructuredData),
Immutable(ImmutableData),
Plain(PlainData),
}
impl Data {
pub fn name(&self) -> XorName {
match *self {
Data::Structured(ref data) => data.name(),
Data::Immutable(ref data) => data.name(),
Data::Plain(ref data) => data.name(),
}
}
pub fn identifier(&self) -> DataIdentifier {
match *self {
Data::Structured(ref data) => data.identifier(),
Data::Immutable(ref data) => data.identifier(),
Data::Plain(ref data) => data.identifier(),
}
}
pub fn payload_size(&self) -> usize {
match *self {
Data::Structured(ref data) => data.payload_size(),
Data::Immutable(ref data) => data.payload_size(),
Data::Plain(ref data) => data.payload_size(),
}
}
}
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, RustcEncodable, RustcDecodable)]
pub enum DataIdentifier {
Structured(XorName, u64),
Immutable(XorName),
Plain(XorName),
}
impl Debug for Data {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match *self {
Data::Structured(ref data) => data.fmt(formatter),
Data::Immutable(ref data) => data.fmt(formatter),
Data::Plain(ref data) => data.fmt(formatter),
}
}
}
impl DataIdentifier {
pub fn name(&self) -> XorName {
match *self {
DataIdentifier::Structured(name, tag) => StructuredData::compute_name(tag, &name),
DataIdentifier::Immutable(name) |
DataIdentifier::Plain(name) => name,
}
}
}
#[cfg(test)]
mod test {
extern crate rand;
use super::*;
use sodiumoxide::crypto::sign;
use sodiumoxide::crypto::hash::sha256;
use xor_name::XorName;
#[test]
fn data_name() {
let keys = sign::gen_keypair();
let owner_keys = vec![keys.0];
match StructuredData::new(0,
rand::random(),
0,
vec![],
owner_keys.clone(),
vec![],
Some(&keys.1)) {
Ok(structured_data) => {
assert_eq!(structured_data.clone().name(),
Data::Structured(structured_data.clone()).name());
assert_eq!(DataIdentifier::Structured(*structured_data.get_identifier(),
structured_data.get_type_tag()),
structured_data.identifier());
}
Err(error) => panic!("Error: {:?}", error),
}
let value = "immutable data value".to_owned().into_bytes();
let immutable_data = ImmutableData::new(value);
assert_eq!(immutable_data.name(),
Data::Immutable(immutable_data.clone()).name());
assert_eq!(immutable_data.identifier(),
DataIdentifier::Immutable(immutable_data.name()));
let name = XorName(sha256::hash(&[]).0);
let plain_data = PlainData::new(name, vec![]);
assert_eq!(plain_data.name(), Data::Plain(plain_data.clone()).name());
assert_eq!(plain_data.identifier(),
DataIdentifier::Plain(plain_data.name()));
}
#[test]
fn data_payload_size() {
let keys = ::sodiumoxide::crypto::sign::gen_keypair();
let owner_keys = vec![keys.0];
match StructuredData::new(0,
rand::random(),
0,
vec![],
owner_keys.clone(),
vec![],
Some(&keys.1)) {
Ok(structured_data) => {
assert_eq!(structured_data.payload_size(),
Data::Structured(structured_data).payload_size());
}
Err(error) => panic!("Error: {:?}", error),
}
let value = "immutable data value".to_owned().into_bytes();
let immutable_data = ImmutableData::new(value);
assert_eq!(immutable_data.payload_size(),
Data::Immutable(immutable_data).payload_size());
let name = XorName(sha256::hash(&[]).0);
let plain_data = PlainData::new(name, vec![]);
assert_eq!(plain_data.payload_size(),
Data::Plain(plain_data).payload_size());
}
#[test]
fn data_request_name() {
let name = XorName(sha256::hash(&[]).0);
let tag = 0;
assert_eq!(StructuredData::compute_name(tag, &name),
DataIdentifier::Structured(name, tag).name());
let actual_name = DataIdentifier::Immutable(name).name();
assert_eq!(name, actual_name);
assert_eq!(name, DataIdentifier::Plain(name).name());
}
}