good advice. the problem with the style of nested function calls is the data flows inward out, the "pipe" style or simply binding intermediate values to named variables make the code and data flow in the same direction which is generally easier to read and understand.
I just want to add, some people coming from other languages tends to nest function calls simply to avoid binding intermediate values to names out of habit.
for example, most other languages don't allow or at least warn about variable shadowing, so people decide to write code in this style (pseudo code):
var my_foo =
just because otherwise they are forced to name things, which they don't want:
var foo_tmp1 = load_saved_foo("foo.json");
var foo_tmp2 = deserialize_foo(foo_tmp1);
var foo = validate_foo(foo_tmp2);
in rust, thanks to the language's type system and compiler's analysis capability, you have the freedom to write:
let foo = load("foo.json");
let foo = deserialize(foo);
let foo = validate(foo);
of course I'm not saying this style is better than alternatives. I just say rust can change the way to write code due to seemingly insignificant small details.
combine with the extension trait mechanism (write your own specialized tap!), you can wrap these functions into associated functions (i.e. "methods") and turn it into the "pipe" style:
let foo = load("foo.json")
but this needs significant more work, I would just use tap most of time.