Hacktoberfest Week 2
Tags: opensource, hacktoberfest, rust, osd600
Published: 2021-10-16 02:01:29

Hey everyone! My previous week for Hacktoberfest can be read here: {% post antoniobennett/hacktoberfest-week-1-4ebc %}

## Project 
Let me start off by saying this week was awesome! This week I worked on a discord bot named [parrot](https://github.com/aquelemiguel/parrot) which is something I've never done before. It is written in rust and is in the early stages of development. 

### Issue
The [issue](https://github.com/aquelemiguel/parrot/issues/10) I was assigned this week was to implement the `!playtop` command. This command when used will place the requested song or playlist at the top of the queue.

### PR
Now let me tell you I racked my brain for a while to think of an elegant solution to this problem. Lets look on how to modify a queue. The `modify_queue()` function is defined on the type `trackQueue` and takes a closure as an argument which exposes the queue, which is essentially a vector of songs. 

Now imagine we have the queue 
```rust 
let queue = vec![0,1,2,3,4];
```
The song at index 0 is always the current playing song. So when manipulating the queue it should remain untouched. To do this we can use the split off function to get the rest of the songs.

```rust
let mut non_playing = queue.split_off(1);
queue: 0
non_playing: 1,2,3,4
```
To the place the newly inserted song (called 5 in this case) we can just rotate the non_playing vec to the right by one which preserves the order.

```rust
non_playing.rotate_right(1)
non_playing: 5,1,2,3,4
```

For playlists I calculated the num of songs in the playlist and subtracted it from the length of non_playing so that the first song of the playlist is at the top. Writing this now, in hindsight I could just call `rotate_right` passing the num of songs in the playlist but meh.

```rust
let rotate_num = non_playing.len() - num_of_songs;
non_playing.rotate_left(rotate_num);
```
Lastly we append non_playing back to the original queue by doing `queue.append(non_playing)`

The final important bit of code is below. Check out the [PR](https://github.com/aquelemiguel/parrot/pull/24) for all the details

```rust
fn reorder_queue(handler: &MutexGuard<Call>, is_playlist: bool, num_of_songs: usize) {
    //Check if we need to move new item to top
    if handler.queue().len() > 2 {
        handler.queue().modify_queue(|queue| {
            let mut non_playing = queue.split_off(1);
            if !is_playlist {
                //rotate the vec to place last added song to the front and maintain order of songs
                non_playing.rotate_right(1);
            } else {
                //We subtract num of songs from temp length so that the first song of playlist is first
                let rotate_num = non_playing.len() - num_of_songs;
                non_playing.rotate_left(rotate_num);
            }
            //Append the new order to current queue which is just the current playing song
            queue.append(&mut non_playing);
        });
    }
}
```
### Overall Thoughts

This week was awesome! I loved working on something new and the task was just right in having me explore new ways of solving a problem. I had a ton of fun and I am excited for the rest of Hacktoberfest. Drop any Rust repo suggestions for me in the comments :)