use sodiumoxide::crypto;
use routing::NameType;
pub fn slice_equal<T: PartialEq>(lhs: &[T], rhs: &[T]) -> bool {
lhs.len() == rhs.len() && lhs.iter().zip(rhs.iter()).all(|(a, b)| a == b)
}
macro_rules! convert_to_array {
($container:ident, $size:expr) => {{
if $container.len() != $size {
None
} else {
use std::mem;
let mut arr : [_; $size] = unsafe { mem::uninitialized() };
for element in $container.into_iter().enumerate() {
let old_val = mem::replace(&mut arr[element.0], element.1);
mem::forget(old_val);
}
Some(arr)
}
}};
}
pub fn name(public_keys: &(crypto::sign::PublicKey, crypto::box_::PublicKey), type_tag: u64,
signature: &crypto::sign::Signature) -> NameType {
let combined_iter = (public_keys.0).0.into_iter().chain((public_keys.1).0.into_iter());
let mut combined: Vec<u8> = Vec::new();
for iter in combined_iter {
combined.push(*iter);
}
for i in type_tag.to_string().into_bytes().into_iter() {
combined.push(i);
}
for i in 0..crypto::sign::SIGNATUREBYTES {
combined.push(signature.0[i]);
}
NameType(crypto::hash::sha512::hash(&combined).0)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn compare_u8_equal() {
let data = "some data".to_string().into_bytes();
assert!(slice_equal(&data, &data));
let data_copy = data.clone();
assert!(slice_equal(&data, &data_copy));
assert!(slice_equal(&data_copy, &data));
}
#[test]
fn compare_u8_not_equal() {
let data1 = "some data".to_string().into_bytes();
let data2 = "some daty".to_string().into_bytes();
assert!(!slice_equal(&data1, &data2));
assert!(!slice_equal(&data2, &data1));
}
#[test]
fn compare_u8_unequal_length() {
let data1 = "some dat".to_string().into_bytes();
let data2 = "some data".to_string().into_bytes();
assert!(!slice_equal(&data1, &data2));
assert!(!slice_equal(&data2, &data1));
}
#[test]
fn compare_string_equal() {
let one = "some string".to_string();
let two = "some two".to_string();
let mut data = Vec::<String>::with_capacity(2);
data.push(one);
data.push(two);
assert!(slice_equal(&data, &data));
let data2 = data.clone();
assert!(slice_equal(&data, &data2));
assert!(slice_equal(&data2, &data));
}
#[test]
fn copy_strings_to_array() {
let one = "some string".to_string();
let two = "some two".to_string();
let mut data = Vec::<String>::with_capacity(2);
data.push(one);
data.push(two);
let data2 = data.clone();
let result = convert_to_array!(data2, 2).unwrap();
assert!(slice_equal(&data, &result));
}
#[test]
fn copy_strings_to_bad_array() {
let one = "some string".to_string();
let two = "some two".to_string();
let mut data = Vec::<String>::with_capacity(2);
data.push(one);
data.push(two);
let data2 = data.clone();
assert!(convert_to_array!(data2, 1).is_none());
assert!(convert_to_array!(data, 3).is_none());
}
}