One of the conveniences offered by JavaScript's jQuery is the ability to chain methods like so:
$(document).ready(function() {
$('#dvContent')
.addClass('dummy')
.css('color', 'red')
.fadeIn('slow');
});
Instead of the more verbose non-chained way of writing the same:
$(document).ready(function() {
$('#dvContent').addClass('dummy');
$('#dvContent').css('color', 'red');
$('#dvContent').fadeIn('slow');
});
Above jQuery code courtesy of jquerybyexample.net.
This is possible because the $(selector) function in jQuery returns a jQuery reference to whatever is indicated by selector, and it is standard for jQuery functions that don't return some type of value (i.e. would otherwise be void) to return the jQuery reference from $(selector) so that the next function in the chain can make use of it.
In Rust, however, this seems impossible.
Let's implement this in pseudo-Rust:
fn $(selector: &Selector) -> JQueryReference {
JQuery::get(selector)
}
So far so good...
impl Chainable for JQueryReference {
fn addClass(&self, class: String) -> Self {
deep_frontendy_stuff_add_class(&self, class);
self
}
}
Ooh, no bueno, that deep_frontendy_stuff_add_class() function can't modify self. Oh I know, I'll just make the reference mutable!
impl Chainable for JQueryReference {
fn addClass(&mut self, class: String) -> Self {
deep_frontendy_stuff_add_class(&mut self, class);
self
}
}
Cool, that worked! But wait, what if I want to go old school and not use the fancy chained types?
$("#dvContent".to_string()).addClass("dummy".to_string());
$("#dvContent".to_string()).css("color".to_string(), "red".to_string());
Nooooooooo! The borrow checker is at it again!
How do I implement such behavior, and if you wouldn't mind, please be as descriptive as possible about why. This question is really an example to help understand the language.