How it works...

The protagonist of this recipe is RefCell, a wrapper around any type that moves the borrow checker's rule enforcement from compile time to runtime. The basics are pretty easy, you borrow the underlying value immutably by calling .borrow() and borrow it mutably by calling .borrow_mut(). If you don't follow the golden rule of only having multiple readers or one single writer at the same time, the program goes into panic!. One application for this is making members of your structs mutable even though your struct itself is immutable. The best use case to show where this is useful is mocking, the art of faking infrastructure for testing purposes.

The idea of our example is as follows, we want to send a newsletter to every customer that is interested. For that, we have the EmailSender trait[1], which just specifies a method to send an Email and return a response[2]. It's good practice to try to define functionality through traits in order to mock them.

Our publish_news function [19] takes a message, an EmailSender and a slice of Customer (please don't imagine that literally), and sends the message to all customers who want to receive news. If it encounters an error, it returns None[32], otherwise, it returns the number of newsletters it sent [36].

You probably don't want to send an email to your customers every time you test your code, which is why we create MockEmailSender[49] inside the test configuration, which doesn't actually send anything but instead stores all mail in a Vec [64]. In order to do this, it needs to modify its member despite being immutable. That's exactly what RefCell is for! Thanks to this, we can efficiently test publish_news(), as we can access all messages it would have sent and compare them with what we expect.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.147.193