Skip to content

Commit

Permalink
Add some class definations for swagger
Browse files Browse the repository at this point in the history
  • Loading branch information
an-tao committed Aug 18, 2021
1 parent c1fd1ea commit 679b3de
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 207 deletions.
1 change: 1 addition & 0 deletions drogon_ctl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(ctl_sources
create_plugin.cc
create_project.cc
create_view.cc
HandlerParser.cc
create_swagger.cc
help.cc
main.cc
Expand Down
168 changes: 168 additions & 0 deletions drogon_ctl/HandlerParser.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include "HandlerParser.h"
#include <iostream>
#include <regex>

using namespace drogon::internal;

std::pair<std::string, std::string> StructNode::findContentOfClassOrNameSpace(
const std::string &content,
std::string::size_type start)
{
int braces = 0;
std::string::size_type pos1{start};
std::string::size_type pos2{content.size() - 1};
for (auto i = start; i < content.size(); i++)
{
if (content[i] == '{')
{
braces++;
if (braces == 1)
{
pos1 = i + 1;
}
}
else if (content[i] == '}')
{
braces--;
if (braces == 0)
{
pos2 = i;
break;
}
}
}
return std::pair<std::string, std::string>(content.substr(pos1,
pos2 - pos1),
content.substr(pos2 + 1));
}
std::pair<StructNodePtr, std::string> StructNode::findClass(
const std::string &content)
{
LOG_DEBUG << "findClass: " << content;
if (content.empty())
return std::pair<StructNodePtr, std::string>(nullptr, "");
std::regex rx(R"(class[ \r\n]+([^ \r\n\{]+)[ \r\n\{:]+)");
std::smatch results;
if (std::regex_search(content, results, rx))
{
assert(results.size() > 1);
auto nextPart =
findContentOfClassOrNameSpace(content, results.position());
return std::pair<StructNodePtr, std::string>(
std::make_shared<StructNode>(nextPart.first,
results[1].str(),
kClass),
nextPart.second);
}
return std::pair<StructNodePtr, std::string>(nullptr, "");
}
std::tuple<std::string, StructNodePtr, std::string> StructNode::findNameSpace(
const std::string &content)
{
LOG_DEBUG << "findNameSpace";
if (content.empty())
return std::tuple<std::string, StructNodePtr, std::string>("",
nullptr,
"");
std::regex rx(R"(namespace[ \r\n]+([^ \r\n]+)[ \r\n]*\{)");
std::smatch results;
if (std::regex_search(content, results, rx))
{
assert(results.size() > 1);
auto pos = results.position();
auto first = content.substr(0, pos);
auto nextPart = findContentOfClassOrNameSpace(content, pos);
auto npNodePtr = std::make_shared<StructNode>(nextPart.first,
results[1].str(),
kNameSpace);

return std::tuple<std::string, StructNodePtr, std::string>(
first, npNodePtr, nextPart.second);
}
else
{
return std::tuple<std::string, StructNodePtr, std::string>("",
nullptr,
"");
}
}
std::vector<StructNodePtr> StructNode::parse(const std::string &content)
{
std::vector<StructNodePtr> res;
auto t = findNameSpace(content);
if (std::get<1>(t))
{
res.emplace_back(std::get<1>(t));
auto firstPart = std::get<0>(t);
while (1)
{
auto p = findClass(firstPart);
if (p.first)
{
res.emplace_back(p.first);
firstPart = p.second;
}
else
{
break;
}
}
auto subsequentNode = parse(std::get<2>(t));
for (auto &node : subsequentNode)
{
res.emplace_back(node);
}
return res;
}
std::string classPart = content;
while (1)
{
auto p = findClass(classPart);
if (p.first)
{
res.emplace_back(p.first);
classPart = p.second;
}
else
{
break;
}
}
return res;
}
void StructNode::print(int indent) const
{
std::string ind(indent, ' ');
std::cout << ind;
switch (type_)
{
case kRoot:
{
std::cout << "Root\n" << ind << "{\n";
break;
}
case kClass:
{
std::cout << "class " << name_ << "\n" << ind << "{\n";
break;
}
case kNameSpace:
{
std::cout << "namespace " << name_ << "\n" << ind << "{\n";
break;
}
}

for (auto child : children_)
{
child->print(indent + 2);
}
if (type_ == kClass)
{
std::cout << content_ << "\n";
}
std::cout << ind << "}";
if (type_ == kClass)
std::cout << ";";
std::cout << "\n";
}
100 changes: 100 additions & 0 deletions drogon_ctl/HandlerParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#pragma once
#include <drogon/HttpTypes.h>
#include <trantor/utils/Logger.h>
#include <vector>
#include <memory>
#include <string>
#include <tuple>

namespace drogon
{
namespace internal
{
class StructNode;
using StructNodePtr = std::shared_ptr<StructNode>;
class StructNode
{
public:
enum NodeType
{
kRoot = 0,
kClass,
kNameSpace
};

StructNode(const std::string &content,
const std::string &name,
NodeType type = kRoot)
: type_(type), name_(name), content_(content)
{
LOG_DEBUG << "new node:" << name << "-" << type;
if (type != kClass)
children_ = parse(content);
}
const std::string &content() const
{
return content_;
}
const std::string &name() const
{
return name_;
}
NodeType type() const
{
return type_;
}
void print() const
{
print(0);
}

private:
std::vector<StructNodePtr> children_;
std::string content_;
NodeType type_;
std::string name_;
std::pair<std::string, std::string> findContentOfClassOrNameSpace(
const std::string &content,
std::string::size_type start);
std::pair<StructNodePtr, std::string> findClass(const std::string &content);
std::tuple<std::string, StructNodePtr, std::string> findNameSpace(
const std::string &content);
std::vector<StructNodePtr> parse(const std::string &content);
void print(int indent) const;
};

class ParametersInfo
{
public:
std::string getName() const;
std::string getType() const;
std::string getConstraint() const;
};
class RoutingInfo
{
public:
std::string getPath() const;
std::vector<std::string> getFilters() const;
std::vector<drogon::HttpMethod> getHttpMethods() const;
std::string getScripts() const;
std::string getContentType() const;
std::string getReturnContentType() const;
std::vector<ParametersInfo> getParameterInfo() const;
std::vector<ParametersInfo> getReturnParameterInfo() const;
};

class HandlerInfo
{
public:
std::string getClassName() const;
std::string getNamespace() const;
std::vector<RoutingInfo> getRoutingInfo() const;
};
class HandlerParser
{
public:
std::vector<HandlerInfo> parse();
HandlerParser(const StructNodePtr root);
};
} // namespace internal
} // namespace drogon
Loading

0 comments on commit 679b3de

Please sign in to comment.