expry 0.1.2

Execute an expression on an encoded (binary) value, yielding another binary value (either in decoded or encoded form). Supports custom functions. Supports parsing the expression and converting the expression to bytecode.
Documentation
#![allow(dead_code)]
#![cfg_attr(not(feature = "std"), no_std)]

use core::mem::size_of_val;
use core::convert::Infallible;

// from https://github.com/mzabaluev/unwrap-infallible/blob/master/src/lib.rs
/// Unwrapping an infallible result into its success value.
pub trait UnwrapInfallible {
    /// Type of the `Ok` variant of the result.
    type Ok;

    /// Unwraps a result, returning the content of an `Ok`.
    ///
    /// Unlike `Result::unwrap`, this method is known to never panic
    /// on the result types it is implemented for. Therefore, it can be used
    /// instead of `unwrap` as a maintainability safeguard that will fail
    /// to compile if the error type of the `Result` is later changed
    /// to an error that can actually occur.
    fn unwrap_infallible(self) -> Self::Ok;
}
impl<T> UnwrapInfallible for Result<T, Infallible> {
    type Ok = T;
    fn unwrap_infallible(self) -> T {
        self.unwrap_or_else(|never| match never {})
    }
}

#[derive(Debug, Copy, Clone)]
pub struct EncodingError {
    pub line_nr: u32,
}

fn raw_read_bytes(reader: &[u8], size: usize) -> Result<(&[u8], &[u8]), EncodingError> {
    if reader.len() < size {
        return Err(EncodingError { line_nr: line!()});
    }
    let value = &reader[0..size];
    Ok((value, &reader[size..]))
}
fn raw_read_f32(reader: &[u8]) -> Result<(f32, &[u8]), EncodingError> {
    if reader.len() < 4 {
        return Err(EncodingError { line_nr: line!()});
    }
    let mut array : [u8; 4] = reader[0..4]
        .try_into()
        .expect("not enough bytes for 4-byte float");
    array.reverse();
    let f = f32::from_le_bytes(array);
    Ok((f, &reader[4..]))
}
fn raw_read_f64(reader: &[u8]) -> Result<(f64, &[u8]), EncodingError> {
    if reader.len() < 8 {
        return Err(EncodingError { line_nr: line!()});
    }
    let mut array : [u8; 8] = reader[0..8]
        .try_into()
        .expect("not enough bytes for 8-byte float");
    array.reverse();
    let f = f64::from_le_bytes(array);
    Ok((f, &reader[8..]))
}
fn raw_read_u8(reader: &[u8]) -> Result<(u8, &[u8]), EncodingError> {
    if reader.is_empty() {
        return Err(EncodingError { line_nr: line!()});
    }
    let value = reader[0];
    Ok((value, &reader[1..]))
}
fn raw_read_var_u64(reader: &[u8]) -> Result<(u64,&[u8]), EncodingError> {
    // // optimize common cases
    // if reader.len() >= 4 {
    //     let first = reader[0] as u64;
    //     if (first & 0b10000000) == 0 {
    //         return Ok((first, 1));
    //     }
    //     if (first & 0b11000000) == 0b10000000 {
    //         return Ok((((first & 0b00111111) << 8) | reader[1] as u64, 2));
    //     }
    //     if (first & 0b11100000) == 0b11000000 {
    //         return Ok((
    //             ((first & 0b00011111) << 16) | (reader[1] as u64) << 8 | (reader[2] as u64),
    //             3,
    //         ));
    //     }
    //     if (first & 0b11110000) == 0b11100000 {
    //         return Ok((
    //             ((first & 0b00001111) << 24)
    //                 | (reader[1] as u64) << 16
    //                 | (reader[2] as u64) << 8
    //                 | (reader[3] as u64),
    //             4,
    //         ));
    //     }
    // }
    if reader.is_empty() {
        return Err(EncodingError { line_nr: line!()});
    }
    // inspired by unicode. First bits indicate the length:
    // if first bit is 0 -> length is 1 byte
    // if first two bits are 10 -> length is 2 bytes
    // if first three bits are 110 -> length is 3 bytes
    // ...
    // if all 8 bytes are 1's -> length is 9 bytes (so 64-bits int fits)
    let first = reader[0] as u64;
    if (first & 0b10000000) == 0 {
        return Ok((first,&reader[1..]));
    }
    // if size_of::<T>() < 2 {
    //     return Err(EncodingError {});
    // }
    if (first & 0b11000000) == 0b10000000 {
        if reader.len() < 2 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00111111) << 8) | reader[1] as u64;
        return Ok((value,&reader[2..]));
    }
    // if size_of::<T>() < 4 {
    //     return Err(EncodingError {});
    // }
    if (first & 0b11100000) == 0b11000000 {
        if reader.len() < 3 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00011111) << 16) | (reader[1] as u64) << 8 | (reader[2] as u64);
        return Ok((value,&reader[3..]));
    }
    if (first & 0b11110000) == 0b11100000 {
        if reader.len() < 4 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00001111) << 24)
                | (reader[1] as u64) << 16
                | (reader[2] as u64) << 8
                | (reader[3] as u64);
        return Ok((value,&reader[4..]));
    }
    // if size_of::<T>() < 8 {
    //     return Err(EncodingError{});
    // }
    if (first & 0b11111000) == 0b11110000 {
        if reader.len() < 5 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00000111) << 32)
                | (reader[1] as u64) << 24
                | (reader[2] as u64) << 16
                | (reader[3] as u64) << 8
                | (reader[4] as u64);
        return Ok((value,&reader[5..]));
    }
    if (first & 0b11111100) == 0b11111000 {
        if reader.len() < 6 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00000011) << 40)
                | (reader[1] as u64) << 32
                | (reader[2] as u64) << 24
                | (reader[3] as u64) << 16
                | (reader[4] as u64) << 8
                | (reader[5] as u64);
        return Ok((value,&reader[6..]));
    }
    if (first & 0b11111110) == 0b11111100 {
        if reader.len() < 7 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = ((first & 0b00000001) << 48)
                | (reader[1] as u64) << 40
                | (reader[2] as u64) << 32
                | (reader[3] as u64) << 24
                | (reader[4] as u64) << 16
                | (reader[5] as u64) << 8
                | (reader[6] as u64);
        return Ok((value,&reader[7..]));
    }
    if first == 0b11111110 {
        if reader.len() < 8 {
            return Err(EncodingError { line_nr: line!()});
        }
        let value = (reader[1] as u64) << 48
                | (reader[2] as u64) << 40
                | (reader[3] as u64) << 32
                | (reader[4] as u64) << 24
                | (reader[5] as u64) << 16
                | (reader[6] as u64) << 8
                | (reader[7] as u64);
        return Ok((value,&reader[8..]));
    }
    if reader.len() < 9 {
        return Err(EncodingError { line_nr: line!()});
    }
    let value = u64::from_be_bytes(reader[1..9].try_into().unwrap());
    Ok((value,&reader[9..]))
}

fn sign_extend(x: i64, nbits: u32) -> i64 {
    debug_assert!(nbits <= 64);
	let notherbits = size_of_val(&x) as u32 * 8 - nbits;
  	x.wrapping_shl(notherbits).wrapping_shr(notherbits)
}

fn raw_read_i64(reader: &[u8], size: usize) -> Result<(i64,&[u8]), EncodingError> {
    if size > 8 || reader.len() < size {
        return Err(EncodingError{ line_nr: line!() });
    }
    let mut copy = [0u8; 8];
    let offset = 8 - size;
    copy[offset..8].copy_from_slice(&reader[0..size]);
    let value = i64::from_be_bytes(copy);
    Ok((sign_extend(value, (size as u32) * 8),&reader[size..]))
}

fn raw_read_var_i64(reader: &[u8]) -> Result<(i64, &[u8]), EncodingError> {
    let first = reader[0] as u64;
    let (v,reader) = raw_read_var_u64(reader)?;
    let bits = if (first & 0b10000000) == 0 {
        7
    } else if (first & 0b11000000) == 0b10000000 {
        14
    } else if (first & 0b11100000) == 0b11000000 {
        21
    } else if (first & 0b11110000) == 0b11100000 {
        28
    } else if (first & 0b11111000) == 0b11110000 {
        35
    } else if (first & 0b11111100) == 0b11111000 {
        42
    } else if (first & 0b11111110) == 0b11111100 {
        49
    } else if (first & 0b11111111) == 0b11111110 {
        56
    } else {
        64
    };
    Ok((sign_extend(v as i64, bits),reader))
}

/// Helper to easily read binary values from an u8-slice, triggering EncodingError on
/// out-of-bounds errors.
#[derive(Eq, PartialEq, Copy, Clone)]
pub struct RawReader<'a> {
    data: &'a [u8],
}

impl<'a> RawReader<'a> {
    pub fn with(data: &'a [u8]) -> Self {
        Self { data, }
    }

    pub fn read_u8(&mut self) -> Result<u8,EncodingError> {
        let (v,r) = raw_read_u8(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_i64(&mut self, len: usize) -> Result<i64,EncodingError> {
        let (v,r) = raw_read_i64(self.data, len)?;
        self.data = r;
        Ok(v)
    }
    pub fn read_var_u64(&mut self) -> Result<u64,EncodingError> {
        let (v,r) = raw_read_var_u64(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_var_i64(&mut self) -> Result<i64,EncodingError> {
        let (v,r) = raw_read_var_i64(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_bytes(&mut self, len: usize) -> Result<&'a [u8],EncodingError> {
        let (v,r) = raw_read_bytes(self.data, len)?;
        self.data = r;
        Ok(v)
    }

    pub fn len(&self) -> usize {
        self.data.len()
    }

    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    pub fn read_f32(&mut self) -> Result<f32,EncodingError> {
        let (v,r) = raw_read_f32(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_f64(&mut self) -> Result<f64,EncodingError> {
        let (v,r) = raw_read_f64(self.data)?;
        self.data = r;
        Ok(v)
    }

    pub fn read_var_string(&mut self) -> Result<&'a [u8],EncodingError> {
        let length = self.read_var_u64()?;
        self.read_bytes(length as usize)
    }

    pub fn skip(&mut self, length: usize) -> Result<(), EncodingError> {
        if length as usize > self.data.len() {
            return Err(EncodingError { line_nr: line!()});
        }
        self.data = &self.data[length..];
        Ok(())
    }

    pub fn data(&self) -> &'a [u8] {
        self.data
    }

    pub fn truncate(&mut self, max: usize) {
        if self.data.len() > max {
            self.data = &self.data[0..max];
        }
    }
}

pub const fn size_of_i64(i: i64) -> usize {
    if -0x80 <= i && i <= 0x7F {
        return 1;
    }
    if -0x8000 <= i && i <= 0x7FFF {
        return 2;
    }
    if -0x800000 <= i && i <= 0x7FFFFF {
        return 3;
    }
    if -0x80000000 <= i && i <= 0x7FFFFFFF {
        return 4;
    }
    if -0x8000000000 <= i && i <= 0x7FFFFFFFFF {
        return 5;
    }
    if -0x800000000000 <= i && i <= 0x7FFFFFFFFFFF {
        return 6;
    }
    if -0x80000000000000 <= i && i <= 0x7FFFFFFFFFFFFF {
        return 7;
    }
    8
}

pub const fn size_of_var_i64(i: i64) -> usize {
    if -0x40 <= i && i <= 0x3F {
        return 1;
    }
    if -0x2000 <= i && i <= 0x1FFF {
        return 2;
    }
    if -0x100000 <= i && i <= 0x0FFFFF {
        return 3;
    }
    if -0x08000000 <= i && i <= 0x07FFFFFF {
        return 4;
    }
    if -0x0400000000 <= i && i <= 0x03FFFFFFFF {
        return 5;
    }
    if -0x020000000000 <= i && i <= 0x01FFFFFFFFFF {
        return 6;
    }
    if -0x01000000000000 <= i && i <= 0x00FFFFFFFFFFFF {
        return 7;
    }
    if -0x0080000000000000 <= i && i <= 0x007FFFFFFFFFFFFF {
        return 8;
    }
    9
}

pub const fn size_of_var_u64(i: u64) -> usize {
    if i <= 0x7F {
        return 1;
    }
    if i <= 0x3FFF {
        return 2;
    }
    if i <= 0x1FFFFF {
        return 3;
    }
    if i <= 0x0FFFFFFF {
        return 4;
    }
    if i <= 0x07FFFFFFFF {
        return 5;
    }
    if i <= 0x03FFFFFFFFFF {
        return 6;
    }
    if i <= 0x01FFFFFFFFFFFF {
        return 7;
    }
    if i <= 0x00FFFFFFFFFFFFFF {
        return 8;
    }
    9
}

pub fn size_of_var_bytes(s: &[u8]) -> usize {
    size_of_var_u64(s.len() as u64) + s.len()
}

pub trait RawOutput<E> {
    fn write_u8(&mut self, n: u8) -> Result<(),E>;
    fn write_i64(&mut self, n: i64, size: usize) -> Result<(),E>;
    fn write_u64(&mut self, i: u64, size: usize) -> Result<(),E>;
    fn write_var_i64(&mut self, i: i64) -> Result<(),E>;
    fn write_var_u64(&mut self, i: u64) -> Result<(),E>;
    fn write_f32(&mut self, f: f32) -> Result<(),E>;
    fn write_f64(&mut self, f: f64) -> Result<(),E>;
    fn write_bytes(&mut self, s: &[u8]) -> Result<(),E>;
    fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),E>;
    fn swap_range(&mut self, a: usize, b: usize) -> Result<(),E>;
    fn pos(&self) -> usize;
}

pub fn write_with_header<T,E,Output,Header,Body>(writer: &mut Output, header: Header, body: Body) -> Result<T,E>
where
    Output: RawOutput<E>,
    Header: FnOnce(&mut Output, u64) -> Result<(),E>,
    Body: FnOnce(&mut Output) -> Result<T,E>,
{
    let start = writer.pos();
    let retval = body(writer)?;
    let end = writer.pos();
    let length = end - start;
    header(writer, length as u64)?;
    writer.swap_range(start, end)?;
    Ok(retval)
}


pub struct RawWriterLength {
    len: usize,
}

impl RawWriterLength {
    pub const fn new() -> Self { Self { len: 0 } }

    pub const fn length(&self) -> usize {
        self.len
    }
}

impl Default for RawWriterLength {
    fn default() -> Self {
        Self::new()
    }
}

impl RawOutput<Infallible> for RawWriterLength {
    fn write_u8(&mut self, _: u8) -> Result<(),Infallible> {
        self.len += 1;
        Ok(())
    }
    fn write_i64(&mut self, _: i64, size: usize) -> Result<(),Infallible> {
        self.len += size;
        Ok(())
    }

    fn write_u64(&mut self, _: u64, size: usize) -> Result<(),Infallible> {
        self.len += size;
        Ok(())
    }

    fn write_var_i64(&mut self, i: i64) -> Result<(),Infallible> {
        self.len += size_of_var_i64(i);
        Ok(())
    }

    fn write_var_u64(&mut self, i: u64) -> Result<(),Infallible> {
        self.len += size_of_var_u64(i);
        Ok(())
    }

    fn write_f32(&mut self, _: f32) -> Result<(),Infallible> {
        self.len += 4;
        Ok(())
    }

    fn write_f64(&mut self, _: f64) -> Result<(),Infallible> {
        self.len += 8;
        Ok(())
    }

    fn write_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
        self.len += s.len();
        Ok(())
    }

    fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
        self.len += size_of_var_u64(s.len() as u64) as usize + s.len();
        Ok(())
    }

    fn swap_range(&mut self, _a: usize, _b: usize) -> Result<(),Infallible> {
        Ok(())
    }

    fn pos(&self) -> usize {
        self.len
    }
}


/// Helper to easily write binary values to a mut u8-slice, triggering EncodingError on
/// out-of-bounds errors.
pub struct RawWriter<'a> {
    data: &'a mut [u8],
    pos: usize,
}

impl<'a> RawOutput<EncodingError> for RawWriter<'a> {
    fn write_u8(&mut self, n: u8) -> Result<(),EncodingError> {
        self.check(1)?;
        self.data[self.pos] = n;
        self.skip(1)
    }

    fn write_i64(&mut self, i: i64, size: usize) -> Result<(),EncodingError> {
        self.check(size)?;
        let i = i.to_be_bytes();
        let offset = 8 - size;
        for p in 0 .. size {
            self.data[self.pos + p] = i[offset + p];
        }
        self.skip(size)
    }

    fn write_u64(&mut self, i: u64, size: usize) -> Result<(),EncodingError> {
        self.check(size)?;
        let i = i.to_be_bytes();
        let offset = 8 - size;
        for p in 0 .. size {
            self.data[self.pos + p] = i[offset + p];
        }
        self.skip(size)
    }

    fn write_var_i64(&mut self, i: i64) -> Result<(),EncodingError> {
        if (-0x40..=0x3F).contains(&i) { // 1 byte
            return self.write_u8((i as u8) & 0x7F);
        }
        if (-0x2000..=0x1FFF).contains(&i) { // 2 bytes
            return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
        }
        if (-0x100000..=0x0FFFFF).contains(&i) { // 3 bytes
            return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
        }
        if (-0x08000000..=0x07FFFFFF).contains(&i) { // 4 bytes
            return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
        }
        if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { // 5 bytes
            return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
        }
        if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { // 6 bytes
            return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
        }
        if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { // 7 bytes
            return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
        }
        if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { // 8 bytes
            return self.write_u64(((i as u64) & 0x00FFFFFFFFFFFFFF) | (0b11111110 << 56), 8);
        }
        self.check(9)?;
        self.data[self.pos] = 0xFF;
        self.data[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
        self.skip(9)
    }

    fn write_var_u64(&mut self, i: u64) -> Result<(),EncodingError> {
        if i <= 0x7F {
            // 1 bytes
            self.check(1)?;
            self.data[self.pos] = i as u8;
            return self.skip(1);
        }
        if i <= 0x3FFF {
            // 2 bytes
            self.check(2)?;
            self.data[self.pos..self.pos + 2].copy_from_slice(&((i | (0b10000000 << 8)) as u16).to_be_bytes());
            return self.skip(2);
        }
        if i <= 0x1FFFFF {
            // 3 bytes
            self.check(3)?;
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 16 | 0b11000000) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 3].copy_from_slice(&(i as u16).to_be_bytes());
            return self.skip(3);
        }
        if i <= 0x0FFFFFFF {
            // 4 bytes
            self.check(4)?;
            self.data[self.pos..self.pos + 4].copy_from_slice(&((i | (0b11100000 << 24)) as u32).to_be_bytes());
            return self.skip(4);
        }
        if i <= 0x07FFFFFFFF {
            // 5 bytes
            self.check(5)?;
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 32 | 0b11110000) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 5].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(5);
        }
        if i <= 0x03FFFFFFFFFF {
            // 6 bytes
            self.check(6)?;
            self.data[self.pos..self.pos + 2].copy_from_slice(&((i >> 32 | (0b11111000 << 8)) as u16).to_be_bytes());
            self.data[self.pos + 2..self.pos + 6].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(6);
        }
        if i <= 0x01FFFFFFFFFFFF {
            // 7 bytes
            self.check(7)?;
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 48 | 0b11111100) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 3].copy_from_slice(&((i >> 32) as u16).to_be_bytes());
            self.data[self.pos + 3..self.pos + 7].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(7);
        }
        if i <= 0x00FFFFFFFFFFFFFF {
            // 8 bytes
            self.check(8)?;
            self.data[self.pos..self.pos + 8].copy_from_slice(&((i | (0b11111110 << 56)) as u64).to_be_bytes());
            return self.skip(8);
        }
        self.check(9)?;
        self.data[self.pos] = 0xFF;
        self.data[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
        self.skip(9)
    }

    fn write_f32(&mut self, f: f32) -> Result<(),EncodingError> {
        self.check(4)?;
        let mut f = f.to_le_bytes();
        f.reverse();
        self.data[self.pos..self.pos + 4].copy_from_slice(&f);
        self.skip(4)
    }

    fn write_f64(&mut self, f: f64) -> Result<(),EncodingError> {
        self.check(8)?;
        let mut f = f.to_le_bytes();
        f.reverse();
        self.data[self.pos..self.pos + 8].copy_from_slice(&f);
        self.skip(8)
    }

    fn write_bytes(&mut self, s: &[u8]) -> Result<(),EncodingError> {
        self.check(s.len())?;
        self.data[self.pos..self.pos + s.len()].copy_from_slice(s);
        self.skip(s.len())
    }

    fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),EncodingError> {
        self.write_var_u64(s.len() as u64)?;
        self.write_bytes(s)
    }

    fn swap_range(&mut self, a: usize, b: usize) -> Result<(),EncodingError> {
        if a >= self.pos || b >= self.pos || a > b {
            return Err(EncodingError{ line_nr: line!(), });
        }
        self.data[a..self.pos].rotate_left(b - a);
        Ok(())
    }

    fn pos(&self) -> usize {
        self.pos
    }
}

impl<'a> RawWriter<'a> {
    pub fn with(data: &'a mut [u8]) -> Self {
        Self { data, pos: 0, }
    }
    pub fn check(&mut self, len: usize) -> Result<(),EncodingError> {
        if self.pos + len <= self.data.len() {
            Ok(())
        } else {
            Err(EncodingError { line_nr: line!()})
        }
    }
    pub fn left(&self) -> usize {
        self.data.len() - self.pos
    }
    fn skip(&mut self, n: usize) -> Result<(), EncodingError> {
        self.pos += n;
        Ok(())
    }
}

#[derive(Debug)]
pub struct RawString {
    pub data: Vec<u8>,
    pos: usize,
}

impl RawOutput<Infallible> for RawString {
    fn write_u8(&mut self, n: u8) -> Result<(),Infallible> {
        self.extend(1);
        self.data[self.pos] = n;
        self.skip(1)
    }

    fn write_i64(&mut self, i: i64, size: usize) -> Result<(),Infallible> {
        self.extend(size);
        let i = i.to_be_bytes();
        let offset = 8 - size;
        for p in 0 .. size {
            self.data[self.pos + p] = i[offset + p];
        }
        self.skip(size)
    }

    fn write_u64(&mut self, i: u64, size: usize) -> Result<(),Infallible> {
        self.extend(size);
        let i = i.to_be_bytes();
        let offset = 8 - size;
        for p in 0 .. size {
            self.data[self.pos + p] = i[offset + p];
        }
        self.skip(size)
    }

    fn write_var_i64(&mut self, i: i64) -> Result<(),Infallible> {
        if (-0x40..=0x3F).contains(&i) { // 1 byte
            return self.write_u8((i as u8) & 0x7F);
        }
        if (-0x2000..=0x1FFF).contains(&i) { // 2 bytes
            return self.write_u64(((i as u64) & 0x3FFF) | (0b10000000 << 8), 2);
        }
        if (-0x100000..=0x0FFFFF).contains(&i) { // 3 bytes
            return self.write_u64(((i as u64) & 0x1FFFFF) | (0b11000000 << 16), 3);
        }
        if (-0x08000000..=0x07FFFFFF).contains(&i) { // 4 bytes
            return self.write_u64(((i as u64) & 0x0FFFFFFF) | (0b11100000 << 24), 4);
        }
        if (-0x0400000000..=0x03FFFFFFFF).contains(&i) { // 5 bytes
            return self.write_u64(((i as u64) & 0x07FFFFFFFF) | (0b11110000 << 32), 5);
        }
        if (-0x020000000000..=0x01FFFFFFFFFF).contains(&i) { // 6 bytes
            return self.write_u64(((i as u64) & 0x03FFFFFFFFFF) | (0b11111000 << 40), 6);
        }
        if (-0x01000000000000..=0x00FFFFFFFFFFFF).contains(&i) { // 7 bytes
            return self.write_u64(((i as u64) & 0x01FFFFFFFFFFFF) | (0b11111100 << 48), 7);
        }
        if (-0x0080000000000000..=0x007FFFFFFFFFFFFF).contains(&i) { // 8 bytes
            return self.write_u64(((i as u64) & 0x00FFFFFFFFFFFFFF) | (0b11111110 << 56), 8);
        }
        self.extend(9);
        self.data[self.pos] = 0xFF;
        self.data[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
        self.skip(9)
    }

    fn write_var_u64(&mut self, i: u64) -> Result<(),Infallible> {
        if i <= 0x7F {
            // 1 bytes
            self.extend(1);
            self.data[self.pos] = i as u8;
            return self.skip(1);
        }
        if i <= 0x3FFF {
            // 2 bytes
            self.extend(2);
            self.data[self.pos..self.pos + 2].copy_from_slice(&((i | (0b10000000 << 8)) as u16).to_be_bytes());
            return self.skip(2);
        }
        if i <= 0x1FFFFF {
            // 3 bytes
            self.extend(3);
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 16 | 0b11000000) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 3].copy_from_slice(&(i as u16).to_be_bytes());
            return self.skip(3);
        }
        if i <= 0x0FFFFFFF {
            // 4 bytes
            self.extend(4);
            self.data[self.pos..self.pos + 4].copy_from_slice(&((i | (0b11100000 << 24)) as u32).to_be_bytes());
            return self.skip(4);
        }
        if i <= 0x07FFFFFFFF {
            // 5 bytes
            self.extend(5);
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 32 | 0b11110000) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 5].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(5);
        }
        if i <= 0x03FFFFFFFFFF {
            // 6 bytes
            self.extend(6);
            self.data[self.pos..self.pos + 2].copy_from_slice(&((i >> 32 | (0b11111000 << 8)) as u16).to_be_bytes());
            self.data[self.pos + 2..self.pos + 6].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(6);
        }
        if i <= 0x01FFFFFFFFFFFF {
            // 7 bytes
            self.extend(7);
            self.data[self.pos..self.pos + 1].copy_from_slice(&((i >> 48 | 0b11111100) as u8).to_be_bytes());
            self.data[self.pos + 1..self.pos + 3].copy_from_slice(&((i >> 32) as u16).to_be_bytes());
            self.data[self.pos + 3..self.pos + 7].copy_from_slice(&(i as u32).to_be_bytes());
            return self.skip(7);
        }
        if i <= 0x00FFFFFFFFFFFFFF {
            // 8 bytes
            self.extend(8);
            self.data[self.pos..self.pos + 8].copy_from_slice(&((i | (0b11111110 << 56)) as u64).to_be_bytes());
            return self.skip(8);
        }
        self.extend(9);
        self.data[self.pos] = 0xFF;
        self.data[self.pos + 1..self.pos + 9].copy_from_slice(&i.to_be_bytes());
        self.skip(9)
    }

    fn write_f32(&mut self, f: f32) -> Result<(),Infallible> {
        self.extend(4);
        let mut f = f.to_le_bytes();
        f.reverse();
        self.data[self.pos..self.pos + 4].copy_from_slice(&f);
        self.skip(4)
    }

    fn write_f64(&mut self, f: f64) -> Result<(),Infallible> {
        self.extend(8);
        let mut f = f.to_le_bytes();
        f.reverse();
        self.data[self.pos..self.pos + 8].copy_from_slice(&f);
        self.skip(8)
    }

    fn write_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
        self.extend(s.len());
        self.data[self.pos..self.pos + s.len()].copy_from_slice(s);
        self.skip(s.len())
    }

    fn write_var_bytes(&mut self, s: &[u8]) -> Result<(),Infallible> {
        self.write_var_u64(s.len() as u64)?;
        self.write_bytes(s)
    }

    fn swap_range(&mut self, a: usize, b: usize) -> Result<(),Infallible> {
        // if a >= self.pos || b >= self.pos || a > b {
        //     return Err(EncodingError{ line_nr: line!(), });
        // }
        self.data[a..self.pos].rotate_left(b - a);
        Ok(())
    }

    fn pos(&self) -> usize {
        self.pos
    }
}

impl RawString {
    pub fn new() -> Self {
        Self { data: Vec::new(), pos: 0 }
    }
    pub fn with_capacity(capacity: usize) -> Self {
        Self { data: Vec::with_capacity(capacity), pos: 0 }
    }
    pub fn extend(&mut self, len: usize) {
        self.data.resize_with(self.pos + len, || 0u8);
    }
    pub fn shrink_to_fit(&mut self) {
        self.data.shrink_to_fit();
    }
    fn skip(&mut self, n: usize) -> Result<(),Infallible> {
        self.pos += n;
        Ok(())
    }
}

impl Default for RawString {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use crate::*;
    use crate::raw_utils::{RawWriter, RawReader};

    #[test]
    fn fixed_signed_int_test() {
        let mut buffer = vec![0u8; 9];
        for i in -16384..=16384 {
            println!("testing {}", i);
            let mut writer = RawWriter::with(&mut buffer[..]);
            writer.write_i64(i, 2).unwrap();
            let writer_len = writer.left();
            let mut reader = RawReader::with(&buffer[..]);
            let r = reader.read_i64(2).unwrap();
            assert_eq!(i, r);
            assert_eq!(writer_len, reader.len());
        }
        let i : i64 = 36028797018963968;
        println!("leading zeros of {} = {}", i, i.leading_zeros());
        let size = size_of_i64(i);
        println!("testing {} with size {}", i, size);
        let mut writer = RawWriter::with(&mut buffer[..]);
        writer.write_i64(i, size).unwrap();
        let writer_len = writer.left();
        let mut reader = RawReader::with(&buffer[..]);
        let r = reader.read_i64(size).unwrap();
        assert_eq!(i, r);
        assert_eq!(writer_len, reader.len());
    }
    #[quickcheck]
    fn quickcheck_fixed_signed(v: i64) -> bool {
        let mut buffer = vec![0u8; 9];
        let size = size_of_i64(v);
        let mut writer = RawWriter::with(&mut buffer[..]);
        writer.write_i64(v, size).unwrap();
        let writer_len = writer.left();
        let mut reader = RawReader::with(&buffer[..]);
        let r = reader.read_i64(size).unwrap();
        r == v && writer_len == reader.len()
    }

    #[test]
    fn var_signed_int_test() {
        let mut buffer = vec![0u8; 9];
        for i in -65536..=65536 {
            let mut writer = RawWriter::with(&mut buffer[..]);
            writer.write_var_i64(i).unwrap();
            let writer_left = writer.left();
            let mut reader = RawReader::with(&buffer[..]);
            let r = reader.read_var_i64().unwrap();
            println!("checking {}: {:?}", i, r);
            assert_eq!(writer_left, reader.len());
            assert_eq!(i, r);
        }
        for i in [2199023255552_i64, 1048576_i64] {
            println!("testing {}", i);
            let expected_len = size_of_var_i64(i);
            let mut writer = RawWriter::with(&mut buffer[..]);
            writer.write_var_i64(i).unwrap();
            let writer_left = writer.left();
            assert_eq!(expected_len, buffer.len() - writer_left);
            let mut reader = RawReader::with(&buffer[..]);
            let r = reader.read_var_i64().unwrap();
            println!("buffer: {:x?}", &buffer[0..expected_len]);
            assert_eq!(reader.len(), writer_left);
            assert_eq!(i, r);
        }
    }
    #[quickcheck]
    fn quickcheck_i64_var(v: i64) -> bool {
        let mut buffer = vec![0u8; 9];
        let expected_len = size_of_var_i64(v);
        let mut writer = RawWriter::with(&mut buffer[..]);
        writer.write_var_i64(v).unwrap();
        let writer_left = writer.left();
        let mut reader = RawReader::with(&buffer[..]);
        let r = reader.read_var_i64().unwrap();
        expected_len == buffer.len() - writer_left && reader.len() == writer_left && r == v
    }

    #[test]
    fn var_unsigned_int_test() {
        let mut buffer = vec![0u8; 9];
        for i in 0..=0x0FFFF {
            let mut writer = RawWriter::with(&mut buffer[..]);
            writer.write_var_u64(i).unwrap();
            let writer_left = writer.left();
            let mut reader = RawReader::with(&buffer[..]);
            let r = reader.read_var_u64().unwrap();
            assert_eq!(writer_left, reader.len());
            assert_eq!(r, i);
        }
    }
    #[quickcheck]
    fn quickcheck_u64_var(v: u64) -> bool {
        let mut buffer = vec![0u8; 9];
        let mut writer = RawWriter::with(&mut buffer[..]);
        writer.write_var_u64(v).unwrap();
        let writer_left = writer.left();
        let mut reader = RawReader::with(&buffer[..]);
        let r = reader.read_var_u64().unwrap();
        writer_left == reader.len() && r == v
    }

}