miuu_replay 0.1.1

Parse .replay files from the game Marble It Up! Ultra
Documentation
#[derive(Debug, Clone)]
pub struct CircularBuffer<T: Clone> {
    buffer: Vec<Option<T>>,
    start: usize,
    end: usize,
    size: usize,
}

impl<T: Clone> CircularBuffer<T> {
    pub fn new() -> Self {
        Self {
            buffer: Vec::new(),
            start: 0,
            end: 0,
            size: 0,
        }
    }

    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            buffer: vec![None; capacity],
            start: 0,
            end: 0,
            size: 0,
        }
    }

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

    pub fn is_full(&self) -> bool {
        self.size == self.buffer.len()
    }

    pub fn is_empty(&self) -> bool {
        self.size == 0
    }

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

    pub fn fast_front(&self) -> &T {
        &self.buffer[self.start].as_ref().unwrap()
    }

    pub fn fast_back(&self) -> &T {
        &self.buffer[if self.end != 0 {
            self.end
        } else {
            self.capacity() - 1
        }]
        .as_ref()
        .unwrap()
    }

    pub fn get(&self, idx: usize) -> &T {
        let len = self.buffer.len();
        let real_idx = self.start
            + if idx < len - self.start {
                idx
            } else {
                idx - len
            };
        &self.buffer[real_idx].as_ref().unwrap()
    }

    pub fn set(&mut self, idx: usize, value: T) {
        let real_idx = self.internal_index(idx);
        self.buffer[real_idx] = Some(value);
    }

    pub fn internal_index(&self, idx: usize) -> usize {
        let len = self.buffer.len();
        self.start
            + if idx < len - self.start {
                idx
            } else {
                idx - len
            }
    }

    fn increment(&mut self, idx: usize) -> usize {
        let mut num = idx + 1;
        if num == self.capacity() {
            num = 0;
        }

        num
    }

    fn decrement(&mut self, idx: usize) -> usize {
        let mut num = idx;
        if num == 0 {
            num = self.capacity();
        }
        num -= 1;

        num
    }

    pub fn push_back(&mut self, value: T) {
        self.buffer[self.end] = Some(value);
        self.end = self.increment(self.end);

        if self.is_full() {
            self.start = self.end;
        } else {
            self.size += 1;
        }
    }

    pub fn push_front(&mut self, value: T) {
        if self.is_full() {
            self.start = self.decrement(self.start);
            self.end = self.start;
            self.buffer[self.end] = Some(value);
        } else {
            self.start = self.decrement(self.start);
            self.buffer[self.start] = Some(value);
            self.size += 1;
        }
    }

    pub fn pop_back(&mut self) -> Option<T> {
        self.end = self.decrement(self.end);
        let value = std::mem::take(&mut self.buffer[self.end]);
        self.size -= 1;

        value
    }

    pub fn pop_front(&mut self) -> Option<T> {
        let value = std::mem::take(&mut self.buffer[self.start]);
        self.start = self.increment(self.start);
        self.size -= 1;

        value
    }

    pub fn clear(&mut self) {
        self.start = 0;
        self.end = 0;
        self.size = 0;
        self.buffer.clear();
    }

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

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

    pub fn buffer(&self) -> &Vec<Option<T>> {
        &self.buffer
    }
}