Table of content

What is this?

The rules of the game are explained in my original post.

Up until now I have given my self small challenge to solve. It seems to me that I am doing to tasks, learning Rust but also solving problems. My initial aim however was to learn Rust. To try and improve the focus of my endeavor lets try re-writing existing code instead of solving a problem and writing new code.

10th Challenge

Challenge

Solution

So I started with this and it became apparent that it was maybe not really a suitable translation challenge. After so trying back and forward I had a look at the std::collections implementation and came across the following note:

// NOTE: It is almost always better to use `Vec` or `VecDeque` because
/// array-based containers are generally faster,
/// more memory efficient, and make better use of CPU cache.

Note the Rust implementation uses the type NonNull and the NonNull documentation says to use *mut T as this is guaranteed to never be Null. If we look further, the implementation is done using unsafe which is not something I would like to do right now. Part of the reason I’m learning Rust is so my code may be safe. Therefore I will just create a wrapper with the same API as the code I’m trying to translate.

	use std::collections::VecDeque;

	fn main() {

	    let mut q:Queue<i32>=Queue::new();
	    let e1:QueueEntry<i32> = QueueEntry{ data: 3 };

	    assert!(q.is_empty());

	    q.push_head(e1);
	    assert_eq!(q.peek_head().unwrap().data,3);
	    assert_eq!(q.pop_head().unwrap().data,3);

	    let e1 = QueueEntry{ data: 4 };
	    q.push_tail(e1);

	    assert_eq!(q.peek_tail().unwrap().data,4);
	    assert_eq!(q.pop_tail().unwrap().data,4);

	    q.free();

	    assert!(q.is_empty());

	}

	struct QueueEntry<T>{
	    data:T,
	}

	struct Queue<T>{
	    data:VecDeque<QueueEntry<T>>
	}

	impl <T> Queue<T> {

	    fn free (&mut self){
	        self.data.clear();
	    }

	    fn push_head(&mut self,entry:QueueEntry<T>){
	        self.data.push_back(entry);
	    }

	    fn pop_head(&mut self) -> Option<QueueEntry<T>> {
	        self.data.pop_back()
	    }

	    fn peek_head(&mut self) -> Option<&QueueEntry<T>> {
	        self.data.back()
	    }

	    fn push_tail(&mut self,entry:QueueEntry<T>){
	        self.data.push_front(entry);
	    }

	    fn pop_tail(&mut self) -> Option<QueueEntry<T>>{
	        self.data.pop_front()
	    }

	    fn peek_tail(&mut self) -> Option<&QueueEntry<T>>{
	        self.data.back()
	    }

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

	    fn new() -> Queue<T>{
	        Queue{
	            data: Default::default()
	        }
	    }
	}


	

I feel like this was a relatively valuable lesson. I will try to keep up with this translating code challenge method and see how it goes.

See github and playground