dfx-base 1.0.0-beta

A FIX protocol implementation
Documentation
use std::num::Wrapping;

pub trait FixChecksum {
    fn checksum(self) -> Wrapping<u8>;
}

pub trait FixLength {
    fn bytes_len(self) -> u32;
}

macro_rules! impl_checksum_unsigned {
    ($type_name:ident) => {
        impl FixChecksum for $type_name {
            fn checksum(self) -> Wrapping<u8> {
                if self == 0 {
                    Wrapping('0' as u8)
                } else {
                    let mut total = Wrapping(0);
                    let mut tag = self;
                    while tag > 0 {
                        total += Wrapping((tag % 10) as u8) + Wrapping('0' as u8);
                        tag = tag / 10;
                    }
                    total
                }
            }
        }
    };}

macro_rules! impl_bytes_len_unsigned {
    ($type_name:ident) => {
        impl FixLength for $type_name {
            fn bytes_len(self) -> u32 {
                if self == 0 {
                    1
                } else {
                    let mut total = 0;
                    let mut tag = self;
                    while tag > 0 {
                        total += 1;
                        tag = tag / 10;
                    }
                    total
                }
            }
        }
    };}

impl_checksum_unsigned!(u8);
impl_checksum_unsigned!(u16);
impl_checksum_unsigned!(u32);
impl_checksum_unsigned!(u64);
impl_checksum_unsigned!(u128);
impl_bytes_len_unsigned!(u8);
impl_bytes_len_unsigned!(u16);
impl_bytes_len_unsigned!(u32);
impl_bytes_len_unsigned!(u64);
impl_bytes_len_unsigned!(u128);

macro_rules! impl_checksum_signed {
    ($type_name:ident) => {
        impl FixChecksum for $type_name {
            fn checksum(self) -> Wrapping<u8> {
                if self == 0 {
                    Wrapping('0' as u8)
                } else {
                    let checksum_neg = if self < 0 {
                        Wrapping('-' as u8)
                    } else {
                        Wrapping(0)
                    };
                    let mut total = Wrapping(0);
                    let mut tag = self.abs();
                    while tag > 0 {
                        total += Wrapping((tag % 10) as u8) + Wrapping('0' as u8);
                        tag = tag / 10;
                    }
                    total + checksum_neg
                }
            }
        }
    };}

macro_rules! impl_bytes_len_signed {
    ($type_name:ident) => {
        impl FixLength for $type_name {
            fn bytes_len(self) -> u32 {
                if self == 0 {
                    1
                } else {
                    let checksum_neg = if self < 0 {
                        1
                    } else {
                        0
                    };
                    let mut total = 0;
                    let mut tag = self.abs();
                    while tag > 0 {
                        total += 1;
                        tag = tag / 10;
                    }
                    total + checksum_neg
                }
            }
        }
    };}

impl_checksum_signed!(i8);
impl_checksum_signed!(i16);
impl_checksum_signed!(i32);
impl_checksum_signed!(i64);
impl_checksum_signed!(i128);
impl_bytes_len_signed!(i8);
impl_bytes_len_signed!(i16);
impl_bytes_len_signed!(i32);
impl_bytes_len_signed!(i64);
impl_bytes_len_signed!(i128);

impl FixChecksum for &[u8] {
    fn checksum(self) -> Wrapping<u8> {
        self.iter().map(|b| Wrapping(*b)).sum()
    }
}

impl FixLength for &[u8] {
    fn bytes_len(self) -> u32 {
        self.len() as u32
    }
}