[ANN] Practical Rust

A couple of comments:

  • to the HashSet article:
    • what you call "fixed-size slices" are not slices; they are called "arrays" in Rust. Slices are the dynamically-sized counterpart to arrays, spelled [T].

    • What I mean is that you can't always immediately tell what thing you can use the from function on – can you do from(vec)? can you do from(iter)? Only one way to know: ask the compiler.

      This is certainly a useful and practical way of finding out, but it would be important to mention that rustdoc-generated documentation automatically includes trait impls, so it's not guesswork – From is usable when the documentation says so.

    • The implementation doesn't need the empty case. You can just use $()* instead of $()+:

      macro_rules! set {
          ($($x:expr),* $(,)?) => (
              HashSet::from([$($x),*])
          );
      }
      
    • The macro would be more robust and useful in real code if you spelled out the fully-qualified path, i.e. std::collections::HashSet. Otherwise users of the macro may be left wondering why their code doesn't compile and why the compiler complains about the "unknown" HashSet type.

    • We didn't include it because HashSet::from_iter(x.into_iter()) tends to require type annotations

      FromIterator::from_iter() only takes a value that implements IntoIterator; Iterator is not required. So you don't need to explicitly convert at the call site; HashSet::from_iter(the_into_iter) should work as-is. Also note that the idiomatic way would be to .collect() instead.

  • to the router article:
    • Even though it's about types, the text routinely skips over the question of ownership, and often contains example code that has trivial syntax or semantic errors.
      • For example, putting an unsized trait object inside a Handler is in itself problematic (because it will require making the field a generic parameter to make use of unsizing coercions to be usefully instantiable), but it straigh up doesn't work if you want to put the now transitively unsized Route in a Vec.
      • Another example is how the HandlerResult::Ignored variant doesn't give the Request back, even though everything seems to pass the request around by-value (and it's hard to imagine that Request is Copy).
5 Likes