query parameter: add a way to delegate certain parameter

The generic query parameter handlers might not be performant, e.g.,
Expand in the sensor collections. This change adds a way to delegate
query parameter processsing to redfish-core codes:

1. introduced a separate struct in the setUpRedfishRoute function, with
which redfish-core codes can easily set delegation for each parameter;
for example, the children patch of this PR will implement an efficient
handler for sensor collection Expand, top, and skip.
2. introduced a separate Redfish route for delegation; this routes takes
the struct described above and changes the query object so that query
parameters are delegated.
3. in order to avoid copying Query objects and run delegation check
twice, the |setUpRedfishRouteWithDelegation| function sets |delegated|
so that callers can directly use it to determinte if delegation is
needed, and what delegated Queries are

Tested:
1. added unit tests
2. the default redfish route is still working correctly

Signed-off-by: Nan Zhou <nanzhoumails@gmail.com>
Change-Id: I77597ad7e8b40ac179d86dc9be1a35767cc61284
diff --git a/redfish-core/include/query.hpp b/redfish-core/include/query.hpp
index 7db370d..4dd03c6 100644
--- a/redfish-core/include/query.hpp
+++ b/redfish-core/include/query.hpp
@@ -7,9 +7,14 @@
 namespace redfish
 {
 
-[[nodiscard]] inline bool setUpRedfishRoute(crow::App& app,
-                                            const crow::Request& req,
-                                            crow::Response& res)
+// Sets up the Redfish Route and delegates some of the query parameter
+// processing. |queryCapabilities| stores which query parameters will be
+// handled by redfish-core/lib codes, then default query parameter handler won't
+// process these parameters.
+[[nodiscard]] inline bool setUpRedfishRouteWithDelegation(
+    crow::App& app, const crow::Request& req, crow::Response& res,
+    query_param::Query& delegated,
+    const query_param::QueryCapabilities& queryCapabilities)
 {
     BMCWEB_LOG_DEBUG << "setup redfish route";
 
@@ -42,9 +47,9 @@
         return true;
     }
 
+    delegated = query_param::delegate(queryCapabilities, *queryOpt);
     std::function<void(crow::Response&)> handler =
         res.releaseCompleteRequestHandler();
-
     res.setCompleteRequestHandler(
         [&app, handler(std::move(handler)),
          query{*queryOpt}](crow::Response& res) mutable {
@@ -52,4 +57,15 @@
         });
     return true;
 }
+
+// Sets up the Redfish Route. All parameters are handled by the default handler.
+[[nodiscard]] inline bool setUpRedfishRoute(crow::App& app,
+                                            const crow::Request& req,
+                                            crow::Response& res)
+{
+    // This route |delegated| is never used
+    query_param::Query delegated;
+    return setUpRedfishRouteWithDelegation(app, req, res, delegated,
+                                           query_param::QueryCapabilities{});
+}
 } // namespace redfish