use std::fmt;
use base64;
use input::Container;
use {Error, ErrorKind};
impl<'a> From<&'a str> for SecretKey<'a> {
fn from(s: &'a str) -> SecretKey<'a> {
SecretKey {
inner: Container::Borrowed(s.as_bytes()),
}
}
}
impl<'a> From<&'a mut str> for SecretKey<'a> {
fn from(s: &'a mut str) -> SecretKey<'a> {
let bytes = unsafe { s.as_bytes_mut() };
SecretKey {
inner: Container::BorrowedMut(bytes),
}
}
}
impl<'a> From<&'a String> for SecretKey<'a> {
fn from(s: &'a String) -> SecretKey<'a> {
SecretKey {
inner: Container::Borrowed(s.as_bytes()),
}
}
}
impl<'a> From<&'a mut String> for SecretKey<'a> {
fn from(s: &'a mut String) -> SecretKey<'a> {
let bytes = unsafe { s.as_bytes_mut() };
SecretKey {
inner: Container::BorrowedMut(bytes),
}
}
}
impl<'a> From<String> for SecretKey<'a> {
fn from(s: String) -> SecretKey<'static> {
SecretKey {
inner: Container::Owned(s.into_bytes()),
}
}
}
impl<'a> From<&'a [u8]> for SecretKey<'a> {
fn from(bytes: &'a [u8]) -> SecretKey<'a> {
SecretKey {
inner: Container::Borrowed(bytes),
}
}
}
impl<'a> From<&'a mut [u8]> for SecretKey<'a> {
fn from(bytes: &'a mut [u8]) -> SecretKey<'a> {
SecretKey {
inner: Container::BorrowedMut(bytes),
}
}
}
impl<'a> From<&'a Vec<u8>> for SecretKey<'a> {
fn from(bytes: &'a Vec<u8>) -> SecretKey<'a> {
SecretKey {
inner: Container::Borrowed(bytes),
}
}
}
impl<'a> From<&'a mut Vec<u8>> for SecretKey<'a> {
fn from(bytes: &'a mut Vec<u8>) -> SecretKey<'a> {
SecretKey {
inner: Container::BorrowedMut(bytes),
}
}
}
impl<'a> From<Vec<u8>> for SecretKey<'a> {
fn from(bytes: Vec<u8>) -> SecretKey<'static> {
SecretKey {
inner: Container::Owned(bytes),
}
}
}
impl<'a> From<&'a SecretKey<'a>> for SecretKey<'a> {
fn from(sk: &'a SecretKey<'a>) -> SecretKey<'a> {
let bytes = match sk.inner {
Container::Borrowed(ref bytes) => &**bytes,
Container::BorrowedMut(ref bytes) => &**bytes,
Container::Owned(ref bytes) => bytes,
};
SecretKey {
inner: Container::Borrowed(bytes),
}
}
}
impl<'a> From<&'a mut SecretKey<'a>> for SecretKey<'a> {
fn from(sk: &'a mut SecretKey<'a>) -> SecretKey<'a> {
match sk.inner {
Container::Borrowed(ref bytes) => SecretKey {
inner: Container::Borrowed(&**bytes),
},
Container::BorrowedMut(ref mut bytes) => SecretKey {
inner: Container::BorrowedMut(&mut **bytes),
},
Container::Owned(ref mut bytes) => SecretKey {
inner: Container::BorrowedMut(&mut *bytes),
},
}
}
}
impl<'a> fmt::Debug for SecretKey<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "****")
}
}
#[derive(Eq, PartialEq, Hash)]
pub struct SecretKey<'a> {
pub(crate) inner: Container<'a>,
}
impl<'a> SecretKey<'a> {
pub fn from_base64_encoded<S>(s: S) -> Result<SecretKey<'static>, Error>
where
S: AsRef<str>,
{
let bytes = base64::decode_config(s.as_ref(), base64::STANDARD).map_err(|_| {
Error::new(ErrorKind::Base64DecodeError).add_context(format!("&str: {}", s.as_ref()))
})?;
Ok(SecretKey {
inner: Container::Owned(bytes),
})
}
pub fn from_base64_encoded_config<S>(
s: S,
config: base64::Config,
) -> Result<SecretKey<'static>, Error>
where
S: AsRef<str>,
{
let bytes = base64::decode_config(s.as_ref(), config).map_err(|_| {
Error::new(ErrorKind::Base64DecodeError).add_context(format!("&str: {}", s.as_ref()))
})?;
Ok(SecretKey {
inner: Container::Owned(bytes),
})
}
pub fn as_bytes(&self) -> &[u8] {
match self.inner {
Container::Borrowed(ref bytes) => bytes,
Container::BorrowedMut(ref bytes) => bytes,
Container::Owned(ref bytes) => bytes,
}
}
pub fn is_mutable(&self) -> bool {
match self.inner {
Container::Borrowed(_) => false,
_ => true,
}
}
pub fn len(&self) -> usize {
self.as_bytes().len()
}
pub fn to_owned(&self) -> SecretKey<'static> {
SecretKey {
inner: self.inner.to_owned(),
}
}
pub fn to_base64_encoded(&self) -> String {
base64::encode_config(self.as_bytes(), base64::STANDARD)
}
pub fn to_base64_encoded_config(&self, config: base64::Config) -> String {
base64::encode_config(self.as_bytes(), config)
}
pub fn to_str(&self) -> Result<&str, Error> {
let s = ::std::str::from_utf8(self.as_bytes())
.map_err(|_| Error::new(ErrorKind::Utf8EncodeError))?;
Ok(s)
}
}
impl<'a> SecretKey<'a> {
pub(crate) fn validate(&self) -> Result<(), Error> {
if self.len() >= ::std::u32::MAX as usize {
return Err(Error::new(ErrorKind::SecretKeyTooLongError)
.add_context(format!("Length: {}", self.len())));
}
Ok(())
}
}