Kylin/HttpProxy/UrlRouter.h
2023-12-30 00:03:40 +08:00

48 lines
1.7 KiB
C++

#ifndef __URLROUTER_H__
#define __URLROUTER_H__
#include "TemplateMatchs.h"
#include "UrlRouterPrivate.h"
#include <boost/url/segments_encoded_view.hpp>
template <typename Resource>
class UrlRouter : public UrlRouterPrivate {
public:
template <class U>
void insert(std::string_view pattern, U &&v) {
BOOST_STATIC_ASSERT(std::is_same<Resource, U>::value || std::is_convertible<U, Resource>::value ||
std::is_base_of<Resource, U>::value);
using ResourceType =
typename std::decay_t<typename std::conditional_t<std::is_base_of_v<Resource, U>, U, Resource>>;
class Implementation : public AnyResource {
public:
explicit Implementation(U &&u_) : resource(std::forward<U>(u_)) {
}
void const *get() const noexcept override {
return static_cast<Resource const *>(&resource);
}
private:
ResourceType resource;
};
auto resource = std::make_shared<Implementation>(std::forward<U>(v));
insertImpl(pattern, std::dynamic_pointer_cast<AnyResource>(resource));
}
const Resource *find(boost::urls::segments_encoded_view path, TemplateMatchStorageBase &matches) const noexcept {
boost::core::string_view *matches_it = matches.matches();
boost::core::string_view *ids_it = matches.ids();
AnyResource const *p = findImpl(path, matches_it, ids_it);
if (p) {
BOOST_ASSERT(matches_it >= matches.matches());
matches.resize(static_cast<std::size_t>(matches_it - matches.matches()));
return reinterpret_cast<Resource const *>(p->get());
}
matches.resize(0);
return nullptr;
};
};
#endif // __URLROUTER_H__