RustCurious.com
Rust explained carefully.

Lesson 4

Structs and Resources

Structs can hold plain data, or they can represent unique resources with protection against copying.

For Purchase:  Lesson 5

Boost Your Learning

Destruction

With no garbage collector, Rust relies on deterministic destructors to manage the lifecycle of objects. Write types that safely encapsulate raw resources, reason confidently about the scopes of locks, and understand the limitations of Rust's guarantees around resource leakage.

Details...

Coding Practice

Exercise: Video Stats

Open in playground

// https://rustcurious.com/4

// Add fields to track the number of likes and dislikes
// on the video, and add methods so the tests pass.
//
// The tests expect the following methods:
//
// - add_like() -- increment the number of likes
// - add_dislike() -- increment the number of dislikes
// - likes_dislikes() -- return a tuple (likes, dislikes)
// - like_ratio() -- return likes / (likes + dislikes)

pub struct Video {
    title: String,
}

impl Video {
    pub fn new(title: String) -> Video {
        Video {
            title,
        }
    }

    pub fn title(&self) -> &str {
        &self.title
    }
}

// -------------------------------------------------------
// No need to change anything below this line.

#[test]
fn test() {
    let mut video = Video::new(String::from("Structs"));
    assert_eq!(video.title(), "Structs");

    video.add_like();
    video.add_like();
    video.add_like();
    video.add_dislike();
    assert_eq!(video.likes_dislikes(), (3, 1));
    assert_eq!(video.like_ratio(), 0.75);
}

// This test checks that likes_dislikes and like_ratio
// can be called on an immutable video object. This will
// fail if those method declarations take `&mut self`.
#[test]
fn test_immutable() {
    let video = Video::new(String::from("Structs"));
    assert_eq!(video.likes_dislikes(), (0, 0));
    assert!(video.like_ratio().is_nan());
}