@@ -70,21 +70,27 @@ impl<S: SharedExtractor> ExclusiveExtractor for S {
7070
7171/// Top-level extractor for a given request
7272///
73- /// During request handling, we wind up needing to call a function with a
74- /// variable number of arguments whose types are all extractors (either
75- /// `SharedExtractor` or `ExclusiveExtractor`). We achieve this with a separate
76- /// type called `RequestExtractor` that looks just like `ExclusiveExtractor`.
77- /// We can impl this trait on a tuple of any number of types that themselves
78- /// impl `SharedExtractor` or `ExclusiveExtractor` by delegating to each type's
79- /// extractor implementation. There may be at most one `ExclusiveExtractor` in
80- /// the tuple. We require it to be the last argument just to avoid having to
81- /// define the power set of impls.
73+ /// During request handling, we must find and invoke the appropriate
74+ /// consumer-defined handler function. While each of these functions takes a
75+ /// fixed number of arguments, different handler functions may take a different
76+ /// number of arguments. The arguments that can vary between handler functions
77+ /// are all extractors, meaning that they impl `SharedExtractor` or
78+ /// `ExclusiveExtractor`.
8279///
83- /// In practice, `RequestExtractor` is identical to `ExclusiveExtractor`. But
84- /// we use them in different ways. `RequestExtractor` is private, only
85- /// implemented on tuple types, and only used to kick off extraction.
86- /// `ExclusiveExtractor` can be consumer-defined and would generally not be
87- /// implemented on tuple types.
80+ /// This trait helps us invoke various handler functions uniformly, despite them
81+ /// accepting different arguments. To achieve this, we impl this trait for all
82+ /// supported _tuples_ of argument types, which is essentially 0 or more
83+ /// `SharedExtractor`s followed by at most one `ExclusiveExtractor`. This impl
84+ /// essentially does the same thing as any other extractor, and it does it by
85+ /// delegating to the impls of each tuple member.
86+ ///
87+ /// In practice, the trait `RequestExtractor` is identical to
88+ /// `ExclusiveExtractor` and we could use `ExclusiveExtractor` directly. But
89+ /// it's clearer to use distinct types, since they're used differently. To
90+ /// summarize: `RequestExtractor` is private, only implemented on tuple types,
91+ /// and only used to kick off extraction from the top level.
92+ /// `ExclusiveExtractor` s public, implementing types can be consumer-defined,
93+ /// and it would generally not be implemented on tuple types.
8894#[ async_trait]
8995pub trait RequestExtractor : Send + Sync + Sized {
9096 /// Construct an instance of this type from a `RequestContext`.
0 commit comments