Circular FIFO Buffer
Your code looks pretty decent. My two cents:


Implement Default

impl Default for Fifo {
    fn default() -&gt; Fifo {
        Fifo {
            size: 0,
            read_idx: 0,
            write_idx: 0,
            buffer: [0; FIFO_CAPACITY],
        }
    }
}


Then you could simplify your new to:

pub fn new() -&gt; Fifo {
    Fifo::default()
}

Simplify expressions

L27: self.size = self.size + 1 will become self.size += 1
L40: self.size = self.size - 1 will become self.size -= 1
Replace str error with enums

pub enum FifoError {
    FifoFull,
}

pub fn push(&amp;mut self, item: u8) -&gt; Result&lt;(), FifoError&gt; {
    if self.buffer_full() {
       Err(FifoError::FifoFull)
    } else {
        ...
}

Add assert_eq!(None, buffer.pop()); to the end of every test where feasible, e,g.


pop_item_that_was_pushed_to_buffer
popping_returns_first_pushed_first
pop_beyond_write_index_continuing_on_works
buffer_wraps_around



For further exercices I would recommend:


Implement Iterator/IntoIterator/FromIterator
Next, implement Debug, which is fairly easy (Hint: Take a look at the implementation of Debug for slice)
Make it accept a generic type