int insert()

in include/ylt/standalone/cinatra/coro_radix_tree.hpp [125:224]


  int insert(
      const std::string &path,
      std::function<void(coro_http_request &req, coro_http_response &resp)>
          handler,
      const std::string &method) {
    auto root = this->root;
    int i = 0, n = path.size(), param_count = 0, code = 0;
    while (i < n) {
      if (!root->indices.empty() &&
          (root->indices[0] == type_asterisk || path[i] == type_asterisk ||
           (path[i] != type_colon && root->indices[0] == type_colon) ||
           (path[i] == type_colon && root->indices[0] != type_colon) ||
           (path[i] == type_colon && root->indices[0] == type_colon &&
            path.substr(i + 1, find_pos(path, type_slash, i) - i - 1) !=
                root->children[0]->path))) {
        code = -1;
        break;
      }

      auto child = root->get_child(path[i]);
      if (!child) {
        auto p = find_pos(path, type_colon, i);

        if (p == n) {
          p = find_pos(path, type_asterisk, i);

          root = root->insert_child(path[i], std::make_shared<radix_tree_node>(
                                                 path.substr(i, p - i)));

          if (p < n) {
            root = root->insert_child(
                type_asterisk,
                std::make_shared<radix_tree_node>(path.substr(p + 1)));
            ++param_count;
          }

          code = root->add_handler(handler, method);
          break;
        }

        root = root->insert_child(
            path[i], std::make_shared<radix_tree_node>(path.substr(i, p - i)));

        i = find_pos(path, type_slash, p);

        root = root->insert_child(
            type_colon,
            std::make_shared<radix_tree_node>(path.substr(p + 1, i - p - 1)));
        ++param_count;

        if (i == n) {
          code = root->add_handler(handler, method);
          break;
        }
      }
      else {
        root = child;

        if (path[i] == type_colon) {
          ++param_count;
          i += root->path.size() + 1;

          if (i == n) {
            code = root->add_handler(handler, method);
            break;
          }
        }
        else {
          auto j = 0UL;
          auto m = root->path.size();

          for (; i < n && j < m && path[i] == root->path[j]; ++i, ++j) {
          }

          if (j < m) {
            std::shared_ptr<radix_tree_node> child(
                std::make_shared<radix_tree_node>(root->path.substr(j)));
            child->handler = root->handler;
            child->indices = root->indices;
            child->children = root->children;

            root->path = root->path.substr(0, j);
            root->handler = {};
            root->indices = child->path[0];
            root->children = {child};
          }

          if (i == n) {
            code = root->add_handler(handler, method);
            break;
          }
        }
      }
    }

    if (param_count > this->root->max_params)
      this->root->max_params = param_count;

    return code;
  }