disasm-core 0.5.1

Core crate for disasm library
Documentation
use core::mem;

pub trait ZExtract<U>: Sized {
    fn zextract(&self, pos: u32, len: u32) -> U;
}

pub trait SExtract<S>: Sized {
    fn sextract(&self, pos: u32, len: u32) -> S;
}

macro_rules! impl_extract {
    ($($uint:ty = $sint:ty),+ $(,)?) => (
        $(
            impl ZExtract<$uint> for $uint {
                fn zextract(&self, pos: u32, len: u32) -> $uint {
                    let w = mem::size_of::<$uint>() as u32 * 8;
                    (*self as $uint << (w - pos - len)) >> (w - len)
                }
            }

            impl SExtract<$sint> for $uint {
                fn sextract(&self, pos: u32, len: u32) -> $sint {
                    let w = mem::size_of::<$uint>() as u32 * 8;
                    (*self as $uint << (w - pos - len)) as $sint >> (w - len)
                }
            }
        )+
    );
}

impl_extract! {
    u8 = i8,
    u16 = i16,
    u32 = i32,
    u64 = i64,
    u128 = i128,
}

pub fn zextract<U, T: ZExtract<U>>(value: T, pos: u32, len: u32) -> U {
    value.zextract(pos, len)
}

pub fn sextract<S, T: SExtract<S>>(value: T, pos: u32, len: u32) -> S {
    value.sextract(pos, len)
}

pub trait Deposit: Sized {
    fn deposit<F: Into<Self>>(&self, pos: u32, len: u32, field: F) -> Self;
}

macro_rules! impl_deposit {
    ($($uint:ty = $sint:ty),+ $(,)?) => {
        $(
            impl Deposit for $uint {
                fn deposit<F: Into<Self>>(&self, pos: u32, len: u32, field: F) -> Self {
                    let mask = (1 as $uint << len).wrapping_sub(1) << pos;
                    (*self & !mask) | ((field.into() << pos) & mask)
                }
            }
         )+
    };
}

impl_deposit! {
    u8 = i8,
    u16 = i16,
    u32 = i32,
    u64 = i64,
    u128 = i128,
}

pub fn deposit<T: Deposit, F: Into<T>>(value: T, pos: u32, len: u32, field: F) -> T {
    value.deposit(pos, len, field)
}