110 lines
4.3 KiB
C++
110 lines
4.3 KiB
C++
#include "server/api/parameters_parser.hpp"
|
|
|
|
#include "server/api/match_parameter_grammar.hpp"
|
|
#include "server/api/nearest_parameter_grammar.hpp"
|
|
#include "server/api/route_parameters_grammar.hpp"
|
|
#include "server/api/table_parameter_grammar.hpp"
|
|
#include "server/api/tile_parameter_grammar.hpp"
|
|
#include "server/api/trip_parameter_grammar.hpp"
|
|
|
|
#include <type_traits>
|
|
|
|
namespace osrm::server::api
|
|
{
|
|
|
|
namespace detail
|
|
{
|
|
template <typename T>
|
|
using is_grammar_t =
|
|
std::integral_constant<bool,
|
|
std::is_same<RouteParametersGrammar<>, T>::value ||
|
|
std::is_same<TableParametersGrammar<>, T>::value ||
|
|
std::is_same<NearestParametersGrammar<>, T>::value ||
|
|
std::is_same<TripParametersGrammar<>, T>::value ||
|
|
std::is_same<MatchParametersGrammar<>, T>::value ||
|
|
std::is_same<TileParametersGrammar<>, T>::value>;
|
|
|
|
template <typename ParameterT,
|
|
typename GrammarT,
|
|
typename std::enable_if<detail::is_parameter_t<ParameterT>::value, int>::type = 0,
|
|
typename std::enable_if<detail::is_grammar_t<GrammarT>::value, int>::type = 0>
|
|
std::optional<ParameterT> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
using It = std::decay<decltype(iter)>::type;
|
|
|
|
static const GrammarT grammar;
|
|
|
|
try
|
|
{
|
|
ParameterT parameters;
|
|
const auto ok =
|
|
boost::spirit::qi::parse(iter, end, grammar(boost::phoenix::ref(parameters)));
|
|
|
|
if (ok && iter == end)
|
|
return parameters;
|
|
}
|
|
catch (const qi::expectation_failure<It> &failure)
|
|
{
|
|
// The grammar above using expectation parsers ">" does not automatically increment the
|
|
// iterator to the failing position. Extract the position from the exception ourselves.
|
|
iter = failure.first;
|
|
}
|
|
catch (const boost::numeric::bad_numeric_cast &)
|
|
{
|
|
// this can happen if we get bad numeric values in the request, just handle
|
|
// as normal parser error
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
} // namespace detail
|
|
|
|
template <>
|
|
std::optional<engine::api::RouteParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::RouteParameters, RouteParametersGrammar<>>(iter,
|
|
end);
|
|
}
|
|
|
|
template <>
|
|
std::optional<engine::api::TableParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::TableParameters, TableParametersGrammar<>>(iter,
|
|
end);
|
|
}
|
|
|
|
template <>
|
|
std::optional<engine::api::NearestParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::NearestParameters, NearestParametersGrammar<>>(iter,
|
|
end);
|
|
}
|
|
|
|
template <>
|
|
std::optional<engine::api::TripParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::TripParameters, TripParametersGrammar<>>(iter, end);
|
|
}
|
|
|
|
template <>
|
|
std::optional<engine::api::MatchParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar<>>(iter,
|
|
end);
|
|
}
|
|
|
|
template <>
|
|
std::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter,
|
|
const std::string::iterator end)
|
|
{
|
|
return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar<>>(iter, end);
|
|
}
|
|
|
|
} // namespace osrm::server::api
|