The major types are:
* You implemented Into when you should have implemented From.
* You sliced a slice when you didn't have to.
* You said Ok(x?) when you could have said x.
* You said Vec::new(); push(); push(); when you could have said vec![].
This is consistent with the other pieces of tor-proto, which do not
handle timeouts on their own. It also lets us remove tor-rtcompat
as a dependency from tor-proto, and simplify some of the test cases
to use async_test.
This commit unindents a lot of test code; use git's "-b" flag to
read the parts that matter.
At this point I'm going to pause writing tor-proto tests for a
little while and think about refactoring that could make these tests
simpler. I'm doing way too much copy-paste here.
dalek-crypto is stuck on rand_core 0.5.1, so we've been stuck too.
This commit introduces a compatibility module so that we can wrap
new rand_core instances to make them backward compatible.
The tricks I needed here turned out to be:
* I needed to store the future returned by read_cell() while it is
returning Poll::Pending.
* Since the type of that future is secret, I needed to put it in a
Box<dyn Future>.
* But since that future holds a reference to the DataReader, that
would create a self-referential structure if we tried to store
the DataReader and the future at the same time. So instead, I
had to make an enum() that either holds a DataReader directly,
or holds the future that will give us back the DataReader when
it's done. (I also had to change the read_cell() function so
that it takes ownership of the DataReader, and returns it when
it's finished.) (Daniel Franke explained how to do this.)
* Finally, I couldn't figure out how to change the enum's type
in-place, so I had to wrap it in an Option<>. (Daniel Franke
says this isn't actually necessary.)
I've noted a couple of places in the read code where I want to
handle errors and closes more carefully.
These new (internal so far) APIs correspond more closely to what
we'll need for AsyncRead and AsyncWrite.
We also make write methods take a mutable reference to self, since
that seems to be (closer to) what the AsyncRead/AsyncWrite code
expects.
For these, we need to call tor_rtcompat::task::block_on() directly,
since they would crash with tokio enabled. Perhaps down the line we
should look for a better fix here.
This is fairly ugly and I think I'll need to mess around with the
feature configuration a while until we get something that's pleasant
to develop with. This still seems like a good idea, though, since
we _will_ need to be executor-agnostic in the end, or we'll have no
way to handle wasm or embedded environments.
Later down the road, we'll probably want to use futures::Executor or
futures::Spawn more than having global entry points in
tor_rtcompat. That would probably make our feature story simpler.
Tokio is the default now, since tokio seems to be more heavily used
for performance-critical stuff.
This patch breaks tests; the next one will fix them, albeit
questionably.