2023-07-21 15:28:59 +08:00
|
|
|
#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 {
|
2023-12-30 00:03:40 +08:00
|
|
|
boost::core::string_view *matches_it = matches.matches();
|
|
|
|
boost::core::string_view *ids_it = matches.ids();
|
2023-07-21 15:28:59 +08:00
|
|
|
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__
|