use std::{cmp, fmt, hash, io, mem};
use std::convert::TryFrom;
use bytes::Bytes;
use crate::decode;
use crate::decode::Source;
use crate::encode::PrimitiveContent;
use crate::mode::Mode;
use crate::tag::Tag;
macro_rules! slice_to_builtin {
( signed, $slice:expr, $type:ident, $err:expr) => {{
const LEN: usize = mem::size_of::<$type>();
if $slice.len() > LEN {
Err($err)
}
else {
let mut res = if $slice[0] & 0x80 == 0 { [0; LEN] }
else { [0xFF; LEN] };
res[LEN - $slice.len()..].copy_from_slice($slice);
Ok($type::from_be_bytes(res))
}
}};
( unsigned, $slice:expr, $type:ident, $err:expr) => {{
const LEN: usize = mem::size_of::<$type>();
if $slice[0] & 0x80 != 0 {
Err($err)
}
else {
let val = if $slice[0] == 0 { &$slice[1..] }
else { $slice };
if val.len() == 0 {
Ok(0)
}
else if val.len() > LEN {
Err($err)
}
else {
let mut res = [0; LEN];
res[LEN - val.len()..].copy_from_slice(val);
Ok($type::from_be_bytes(res))
}
}
}};
}
macro_rules! decode_builtin {
( $flavor:ident, $prim:expr, $type:ident) => {{
Self::check_head($prim)?;
let res = {
let slice = $prim.slice_all()?;
slice_to_builtin!(
$flavor, slice, $type, decode::Malformed.into()
)?
};
$prim.skip_all()?;
Ok(res)
}}
}
macro_rules! from_builtin {
( $from:ident, $to:ident) => {
impl From<$from> for $to {
fn from(val: $from) -> $to {
unsafe {
$to::from_bytes_unchecked(val.to_encoded_bytes(Mode::Der))
}
}
}
}
}
macro_rules! builtin_from {
($flavor:ident, $from:ident, $to:ident, $len:expr) => {
impl<'a> TryFrom<&'a $from> for $to {
type Error = OverflowError;
fn try_from(val: &'a $from) -> Result<$to, Self::Error> {
let val = val.as_slice();
slice_to_builtin!($flavor, val, $to, OverflowError(()))
}
}
impl TryFrom<$from> for $to {
type Error = OverflowError;
fn try_from(val: $from) -> Result<$to, Self::Error> {
$to::try_from(&val)
}
}
}
}
#[derive(Clone, Debug)]
pub struct Integer(Bytes);
impl Integer {
unsafe fn from_bytes_unchecked(bytes: Bytes) -> Self {
Integer(bytes)
}
pub fn take_from<S: decode::Source>(
cons: &mut decode::Constructed<S>
) -> Result<Self, S::Err> {
cons.take_primitive_if(Tag::INTEGER, Self::from_primitive)
}
pub fn from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<Self, S::Err> {
let res = prim.take_all()?;
match (res.get(0), res.get(1).map(|x| x & 0x80 != 0)) {
(Some(0), Some(false)) => {
xerr!(return Err(decode::Error::Malformed.into()))
}
(Some(0xFF), Some(true)) => {
xerr!(return Err(decode::Error::Malformed.into()))
}
(None, _) => {
xerr!(return Err(decode::Error::Malformed.into()))
}
_ => { }
}
Ok(Integer(res))
}
pub fn i8_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<i8, S::Err> {
Self::check_head(prim)?;
prim.take_u8().map(|x| x as i8)
}
pub fn i16_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<i16, S::Err> {
decode_builtin!(signed, prim, i16)
}
pub fn i32_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<i32, S::Err> {
decode_builtin!(signed, prim, i32)
}
pub fn i64_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<i64, S::Err> {
decode_builtin!(signed, prim, i64)
}
pub fn i128_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<i128, S::Err> {
decode_builtin!(signed, prim, i128)
}
fn check_head<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<(), S::Err> {
if prim.request(2)? == 0 {
xerr!(return Err(decode::Error::Malformed.into()))
}
let slice = prim.slice();
match (slice.get(0), slice.get(1).map(|x| x & 0x80 != 0)) {
(Some(0), Some(false)) => {
xerr!(Err(decode::Error::Malformed.into()))
}
(Some(0xFF), Some(true)) => {
xerr!(Err(decode::Error::Malformed.into()))
}
_ => Ok(())
}
}
pub fn into_bytes(self) -> Bytes {
self.0
}
pub fn as_slice(&self) -> &[u8] {
self.0.as_ref()
}
pub fn is_zero(&self) -> bool {
self.0[0] == 0
}
pub fn is_positive(&self) -> bool {
if self.0[0] == 0 && self.0.get(1).is_none() {
return false
}
self.0[0] & 0x80 == 0x00
}
pub fn is_negative(&self) -> bool {
self.0[0] & 0x80 == 0x80
}
}
from_builtin!(i8, Integer);
from_builtin!(i16, Integer);
from_builtin!(i32, Integer);
from_builtin!(i64, Integer);
from_builtin!(i128, Integer);
from_builtin!(u8, Integer);
from_builtin!(u16, Integer);
from_builtin!(u32, Integer);
from_builtin!(u64, Integer);
from_builtin!(u128, Integer);
builtin_from!(signed, Integer, i8, 1);
builtin_from!(signed, Integer, i16, 2);
builtin_from!(signed, Integer, i32, 4);
builtin_from!(signed, Integer, i64, 8);
builtin_from!(signed, Integer, i128, 16);
builtin_from!(unsigned, Integer, u8, 1);
builtin_from!(unsigned, Integer, u16, 2);
builtin_from!(unsigned, Integer, u32, 4);
builtin_from!(unsigned, Integer, u64, 8);
builtin_from!(unsigned, Integer, u128, 16);
impl AsRef<Bytes> for Integer {
fn as_ref(&self) -> &Bytes {
&self.0
}
}
impl AsRef<[u8]> for Integer {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl PartialEq for Integer {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl PartialEq<Unsigned> for Integer {
fn eq(&self, other: &Unsigned) -> bool {
self.eq(&other.0)
}
}
impl Eq for Integer { }
impl PartialOrd for Integer {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Integer {
fn cmp(&self, other: &Self) -> cmp::Ordering {
match (self.is_positive(), other.is_positive()) {
(true, true) => {
match self.0.len().cmp(&other.0.len()) {
cmp::Ordering::Equal => {
for (l, r) in self.0.iter().zip(other.0.iter()) {
match l.cmp(r) {
cmp::Ordering::Equal => { }
cmp => return cmp
}
}
cmp::Ordering::Equal
}
cmp => cmp
}
}
(false, false) => {
match self.0.len().cmp(&other.0.len()) {
cmp::Ordering::Equal => {
for (l, r) in self.0.iter().zip(other.0.iter()) {
match l.cmp(r) {
cmp::Ordering::Equal => { }
cmp => return cmp.reverse()
}
}
cmp::Ordering::Equal
}
cmp => cmp.reverse()
}
}
(false, true) => cmp::Ordering::Less,
(true, false) => cmp::Ordering::Greater,
}
}
}
impl hash::Hash for Integer {
fn hash<H: hash::Hasher>(&self, h: &mut H) {
self.0.hash(h)
}
}
impl<'a> PrimitiveContent for &'a Integer {
const TAG: Tag = Tag::INTEGER;
fn encoded_len(&self, _mode: Mode) -> usize {
self.0.len()
}
fn write_encoded<W: io::Write>(
&self,
_mode: Mode,
target: &mut W
) -> Result<(), io::Error> {
target.write_all(self.0.as_ref())
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Unsigned(Integer);
impl Unsigned {
unsafe fn from_bytes_unchecked(bytes: Bytes) -> Self {
Unsigned(Integer::from_bytes_unchecked(bytes))
}
pub fn take_from<S: decode::Source>(
cons: &mut decode::Constructed<S>
) -> Result<Self, S::Err> {
cons.take_primitive_if(Tag::INTEGER, Self::from_primitive)
}
pub fn from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<Self, S::Err> {
Self::check_head(prim)?;
Integer::from_primitive(prim).map(Unsigned)
}
pub fn u8_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<u8, S::Err> {
Self::check_head(prim)?;
match prim.remaining() {
1 => prim.take_u8(),
2 => {
if prim.take_u8()? != 0 {
xerr!(Err(decode::Malformed.into()))
}
else {
prim.take_u8()
}
}
_ => xerr!(Err(decode::Malformed.into()))
}
}
pub fn u16_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<u16, S::Err> {
Self::check_head(prim)?;
match prim.remaining() {
1 => Ok(prim.take_u8()?.into()),
2 => {
Ok(
u16::from(prim.take_u8()?) << 8 |
u16::from(prim.take_u8()?)
)
}
3 => {
if prim.take_u8()? != 0 {
xerr!(return Err(decode::Malformed.into()));
}
let res = {
u16::from(prim.take_u8()?) << 8 |
u16::from(prim.take_u8()?)
};
if res < 0x8000 {
Err(decode::Malformed.into())
}
else {
Ok(res)
}
}
_ => xerr!(Err(decode::Malformed.into()))
}
}
pub fn u32_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<u32, S::Err> {
Self::check_head(prim)?;
decode_builtin!(unsigned, prim, u32)
}
pub fn u64_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<u64, S::Err> {
Self::check_head(prim)?;
decode_builtin!(unsigned, prim, u64)
}
pub fn u128_from_primitive<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<u128, S::Err> {
Self::check_head(prim)?;
decode_builtin!(unsigned, prim, u128)
}
fn check_head<S: decode::Source>(
prim: &mut decode::Primitive<S>
) -> Result<(), S::Err> {
Integer::check_head(prim)?;
if prim.slice().get(0).unwrap() & 0x80 != 0 {
xerr!(Err(decode::Error::Malformed.into()))
}
else {
Ok(())
}
}
pub fn into_bytes(self) -> Bytes {
self.0.into_bytes()
}
pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}
pub fn is_zero(&self) -> bool {
self.0.is_zero()
}
}
from_builtin!(u8, Unsigned);
from_builtin!(u16, Unsigned);
from_builtin!(u32, Unsigned);
from_builtin!(u64, Unsigned);
from_builtin!(u128, Unsigned);
builtin_from!(signed, Unsigned, i8, 1);
builtin_from!(signed, Unsigned, i16, 2);
builtin_from!(signed, Unsigned, i32, 4);
builtin_from!(signed, Unsigned, i64, 8);
builtin_from!(signed, Unsigned, i128, 16);
builtin_from!(unsigned, Unsigned, u8, 1);
builtin_from!(unsigned, Unsigned, u16, 2);
builtin_from!(unsigned, Unsigned, u32, 4);
builtin_from!(unsigned, Unsigned, u64, 8);
builtin_from!(unsigned, Unsigned, u128, 16);
impl AsRef<Integer> for Unsigned {
fn as_ref(&self) -> &Integer {
&self.0
}
}
impl AsRef<Bytes> for Unsigned {
fn as_ref(&self) -> &Bytes {
self.0.as_ref()
}
}
impl AsRef<[u8]> for Unsigned {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl<'a> PrimitiveContent for &'a Unsigned {
const TAG: Tag = Tag::INTEGER;
fn encoded_len(&self, mode: Mode) -> usize {
(&self.0).encoded_len(mode)
}
fn write_encoded<W: io::Write>(
&self,
mode: Mode,
target: &mut W
) -> Result<(), io::Error> {
(&self.0).write_encoded(mode, target)
}
}
#[derive(Clone, Copy, Debug)]
pub struct OverflowError(());
impl fmt::Display for OverflowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "integer out of range")
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Mode;
use crate::decode::Primitive;
#[test]
fn is_positive_negative() {
let neg = [-0xF74402, -0xF744, -0xF7];
let pos = [0xF7, 0xF744, 0xF74402];
for &i in &neg {
assert_eq!(Integer::from(i).is_positive(), false, "{}", i);
assert_eq!(Integer::from(i).is_negative(), true, "{}", i);
}
for &i in &pos {
assert_eq!(Integer::from(i).is_positive(), true, "{}", i);
assert_eq!(Integer::from(i).is_negative(), false, "{}", i);
}
assert_eq!(Integer::from(0).is_positive(), false);
assert_eq!(Integer::from(0).is_negative(), false);
}
#[test]
fn cmp() {
let ints = [-0xF74402, -0xF744, -0xF7, 0, 0xF7, 0xF744, 0xF74402];
for &left in &ints {
for &right in &ints {
assert_eq!(
Integer::from(left).cmp(&Integer::from(right)),
left.cmp(&right),
"comparision of {} and {} failed", left, right
)
}
}
}
#[test]
fn decode_unsigned_builtins() {
assert_eq!(
Primitive::decode_slice(
b"\x00".as_ref(), Mode::Der,
|prim| Unsigned::u8_from_primitive(prim)
).unwrap(),
0
);
assert_eq!(
Primitive::decode_slice(
b"\x7F".as_ref(), Mode::Der,
|prim| Unsigned::u8_from_primitive(prim)
).unwrap(),
0x7f
);
assert_eq!(
Primitive::decode_slice(
b"\x80".as_ref(), Mode::Der,
|prim| Unsigned::u8_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x00\x80".as_ref(), Mode::Der,
|prim| Unsigned::u8_from_primitive(prim)
).unwrap(),
0x80
);
assert_eq!(
Primitive::decode_slice(
b"\x00".as_ref(), Mode::Der,
|prim| Unsigned::u16_from_primitive(prim)
).unwrap(),
0
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34".as_ref(), Mode::Der,
|prim| Unsigned::u16_from_primitive(prim)
).unwrap(),
0x1234
);
assert_eq!(
Primitive::decode_slice(
b"\x00\xA2\x34".as_ref(), Mode::Der,
|prim| Unsigned::u16_from_primitive(prim)
).unwrap(),
0xA234
);
assert_eq!(
Primitive::decode_slice(
b"\xA2\x34".as_ref(), Mode::Der,
|prim| Unsigned::u16_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x00\x12\x34".as_ref(), Mode::Der,
|prim| Unsigned::u16_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x12".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap(),
0x12
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap(),
0x1234
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34\x56".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap(),
0x123456
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap(),
0x12345678
);
assert_eq!(
Primitive::decode_slice(
b"\x00\xA2\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap(),
0xA2345678
);
assert_eq!(
Primitive::decode_slice(
b"\x00\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\xa2\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u32_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x12".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap(),
0x12
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap(),
0x1234567812345678
);
assert_eq!(
Primitive::decode_slice(
b"\0\xa2\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap(),
0xa234567812345678
);
assert_eq!(
Primitive::decode_slice(
b"\0\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x30\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x12".as_ref(), Mode::Der,
|prim| Unsigned::u64_from_primitive(prim)
).unwrap(),
0x12
);
assert_eq!(
Primitive::decode_slice(
b"\x12\x34\x56\x78\x12\x34\x56\x78\
\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u128_from_primitive(prim)
).unwrap(),
0x12345678123456781234567812345678
);
assert_eq!(
Primitive::decode_slice(
b"\0\xa2\x34\x56\x78\x12\x34\x56\x78\
\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u128_from_primitive(prim)
).unwrap(),
0xa2345678123456781234567812345678
);
assert_eq!(
Primitive::decode_slice(
b"\0\x12\x34\x56\x78\x12\x34\x56\x78
\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u128_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x30\x12\x34\x56\x78\x12\x34\x56\x78
\x12\x34\x56\x78\x12\x34\x56\x78".as_ref(), Mode::Der,
|prim| Unsigned::u128_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
}
#[test]
fn decode_signed_builtins() {
assert_eq!(
Primitive::decode_slice(
b"\x00".as_ref(), Mode::Der,
|prim| Integer::i8_from_primitive(prim)
).unwrap(),
0
);
assert_eq!(
Primitive::decode_slice(
b"\xFF".as_ref(), Mode::Der,
|prim| Integer::i8_from_primitive(prim)
).unwrap(),
-1
);
assert_eq!(
Primitive::decode_slice(
b"\x00\xFF".as_ref(), Mode::Der,
|prim| Integer::i8_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x40\xFF".as_ref(), Mode::Der,
|prim| Integer::i8_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x00".as_ref(), Mode::Der,
|prim| Integer::i16_from_primitive(prim)
).unwrap(),
0
);
assert_eq!(
Primitive::decode_slice(
b"\xFF".as_ref(), Mode::Der,
|prim| Integer::i16_from_primitive(prim)
).unwrap(),
-1
);
assert_eq!(
Primitive::decode_slice(
b"\x80\xFF".as_ref(), Mode::Der,
|prim| Integer::i16_from_primitive(prim)
).unwrap(),
-32513
);
assert_eq!(
Primitive::decode_slice(
b"\x80\xFF\x32".as_ref(), Mode::Der,
|prim| Integer::i16_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x00\xFF\x32".as_ref(), Mode::Der,
|prim| Integer::i16_from_primitive(prim)
).unwrap_err(),
decode::Malformed
);
assert_eq!(
Primitive::decode_slice(
b"\x00".as_ref(), Mode::Der,
|prim| Integer::i32_from_primitive(prim)
).unwrap(),
0
);
assert_eq!(
Primitive::decode_slice(
b"\xff".as_ref(), Mode::Der,
|prim| Integer::i32_from_primitive(prim)
).unwrap(),
-1
);
assert_eq!(
Primitive::decode_slice(
b"\x80\xFF".as_ref(), Mode::Der,
|prim| Integer::i32_from_primitive(prim)
).unwrap(),
-32513
);
}
#[test]
fn unsigned_builtin_from() {
let int = Integer(b"\x00".as_ref().into());
assert_eq!(u8::try_from(&int).unwrap(), 0);
assert_eq!(u16::try_from(&int).unwrap(), 0);
assert_eq!(u32::try_from(&int).unwrap(), 0);
assert_eq!(u64::try_from(&int).unwrap(), 0);
assert_eq!(u128::try_from(&int).unwrap(), 0);
assert_eq!(i8::try_from(&int).unwrap(), 0);
assert_eq!(i16::try_from(&int).unwrap(), 0);
assert_eq!(i32::try_from(&int).unwrap(), 0);
assert_eq!(i64::try_from(&int).unwrap(), 0);
assert_eq!(i128::try_from(&int).unwrap(), 0);
let int = Integer(b"\x7F".as_ref().into());
assert_eq!(u8::try_from(&int).unwrap(), 0x7F);
assert_eq!(u16::try_from(&int).unwrap(), 0x7F);
assert_eq!(u32::try_from(&int).unwrap(), 0x7F);
assert_eq!(u64::try_from(&int).unwrap(), 0x7F);
assert_eq!(u128::try_from(&int).unwrap(), 0x7F);
assert_eq!(i8::try_from(&int).unwrap(), 0x7F);
assert_eq!(i16::try_from(&int).unwrap(), 0x7F);
assert_eq!(i32::try_from(&int).unwrap(), 0x7F);
assert_eq!(i64::try_from(&int).unwrap(), 0x7F);
assert_eq!(i128::try_from(&int).unwrap(), 0x7F);
let int = Integer(b"\x80".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert!(u32::try_from(&int).is_err());
assert!(u64::try_from(&int).is_err());
assert!(u128::try_from(&int).is_err());
assert_eq!(i8::try_from(&int).unwrap(), -128);
assert_eq!(i16::try_from(&int).unwrap(), -128);
assert_eq!(i32::try_from(&int).unwrap(), -128);
assert_eq!(i64::try_from(&int).unwrap(), -128);
assert_eq!(i128::try_from(&int).unwrap(), -128);
let int = Integer(b"\x00\x80".as_ref().into());
assert_eq!(u8::try_from(&int).unwrap(), 0x80);
assert_eq!(u16::try_from(&int).unwrap(), 0x80);
assert_eq!(u32::try_from(&int).unwrap(), 0x80);
assert_eq!(u64::try_from(&int).unwrap(), 0x80);
assert_eq!(u128::try_from(&int).unwrap(), 0x80);
let int = Integer(b"\x12\x34".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert_eq!(u16::try_from(&int).unwrap(), 0x1234);
assert_eq!(u32::try_from(&int).unwrap(), 0x1234);
assert_eq!(u64::try_from(&int).unwrap(), 0x1234);
assert_eq!(u128::try_from(&int).unwrap(), 0x1234);
assert!(i8::try_from(&int).is_err());
assert_eq!(i16::try_from(&int).unwrap(), 0x1234);
assert_eq!(i32::try_from(&int).unwrap(), 0x1234);
assert_eq!(i64::try_from(&int).unwrap(), 0x1234);
assert_eq!(i128::try_from(&int).unwrap(), 0x1234);
let int = Integer(b"\xA2\x34".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert!(u32::try_from(&int).is_err());
assert!(u64::try_from(&int).is_err());
assert!(u128::try_from(&int).is_err());
assert!(i8::try_from(&int).is_err());
assert_eq!(i16::try_from(&int).unwrap(), -24012);
assert_eq!(i32::try_from(&int).unwrap(), -24012);
assert_eq!(i64::try_from(&int).unwrap(), -24012);
assert_eq!(i128::try_from(&int).unwrap(), -24012);
let int = Integer(b"\x00\xA2\x34".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert_eq!(u16::try_from(&int).unwrap(), 0xA234);
assert_eq!(u32::try_from(&int).unwrap(), 0xA234);
assert_eq!(u64::try_from(&int).unwrap(), 0xA234);
assert_eq!(u128::try_from(&int).unwrap(), 0xA234);
let int = Integer(b"\x12\x34\x56".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert_eq!(u32::try_from(&int).unwrap(), 0x123456);
assert_eq!(u64::try_from(&int).unwrap(), 0x123456);
assert_eq!(u128::try_from(&int).unwrap(), 0x123456);
assert!(i8::try_from(&int).is_err());
assert!(i16::try_from(&int).is_err());
assert_eq!(i32::try_from(&int).unwrap(), 0x123456);
assert_eq!(i64::try_from(&int).unwrap(), 0x123456);
assert_eq!(i128::try_from(&int).unwrap(), 0x123456);
let int = Integer(b"\x12\x34\x56\x78".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert_eq!(u32::try_from(&int).unwrap(), 0x12345678);
assert_eq!(u64::try_from(&int).unwrap(), 0x12345678);
assert_eq!(u128::try_from(&int).unwrap(), 0x12345678);
assert!(i8::try_from(&int).is_err());
assert!(i16::try_from(&int).is_err());
assert_eq!(i32::try_from(&int).unwrap(), 0x12345678);
assert_eq!(i64::try_from(&int).unwrap(), 0x12345678);
assert_eq!(i128::try_from(&int).unwrap(), 0x12345678);
let int = Integer(b"\xA2\x34\x56\x78".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert!(u32::try_from(&int).is_err());
assert!(u64::try_from(&int).is_err());
assert!(u128::try_from(&int).is_err());
assert!(i8::try_from(&int).is_err());
assert!(i16::try_from(&int).is_err());
assert_eq!(i32::try_from(&int).unwrap(), -1573628296);
assert_eq!(i64::try_from(&int).unwrap(), -1573628296);
assert_eq!(i128::try_from(&int).unwrap(), -1573628296);
let int = Integer(b"\x00\xA2\x34\x56\x78".as_ref().into());
assert!(u8::try_from(&int).is_err());
assert!(u16::try_from(&int).is_err());
assert_eq!(u32::try_from(&int).unwrap(), 0xA2345678);
assert_eq!(u64::try_from(&int).unwrap(), 0xA2345678);
assert_eq!(u128::try_from(&int).unwrap(), 0xA2345678);
}
}