Skip to content

Commit 81ba918

Browse files
committed
Add some class definations for swagger
1 parent 4c77e86 commit 81ba918

File tree

4 files changed

+270
-207
lines changed

4 files changed

+270
-207
lines changed

drogon_ctl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(ctl_sources
77
create_plugin.cc
88
create_project.cc
99
create_view.cc
10+
HandlerParser.cc
1011
create_swagger.cc
1112
help.cc
1213
main.cc

drogon_ctl/HandlerParser.cc

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#include "HandlerParser.h"
2+
#include <iostream>
3+
#include <regex>
4+
5+
using namespace drogon::internal;
6+
7+
std::pair<std::string, std::string> StructNode::findContentOfClassOrNameSpace(
8+
const std::string &content,
9+
std::string::size_type start)
10+
{
11+
int braces = 0;
12+
std::string::size_type pos1{start};
13+
std::string::size_type pos2{content.size() - 1};
14+
for (auto i = start; i < content.size(); i++)
15+
{
16+
if (content[i] == '{')
17+
{
18+
braces++;
19+
if (braces == 1)
20+
{
21+
pos1 = i + 1;
22+
}
23+
}
24+
else if (content[i] == '}')
25+
{
26+
braces--;
27+
if (braces == 0)
28+
{
29+
pos2 = i;
30+
break;
31+
}
32+
}
33+
}
34+
return std::pair<std::string, std::string>(content.substr(pos1,
35+
pos2 - pos1),
36+
content.substr(pos2 + 1));
37+
}
38+
std::pair<StructNodePtr, std::string> StructNode::findClass(
39+
const std::string &content)
40+
{
41+
LOG_DEBUG << "findClass: " << content;
42+
if (content.empty())
43+
return std::pair<StructNodePtr, std::string>(nullptr, "");
44+
std::regex rx(R"(class[ \r\n]+([^ \r\n\{]+)[ \r\n\{:]+)");
45+
std::smatch results;
46+
if (std::regex_search(content, results, rx))
47+
{
48+
assert(results.size() > 1);
49+
auto nextPart =
50+
findContentOfClassOrNameSpace(content, results.position());
51+
return std::pair<StructNodePtr, std::string>(
52+
std::make_shared<StructNode>(nextPart.first,
53+
results[1].str(),
54+
kClass),
55+
nextPart.second);
56+
}
57+
return std::pair<StructNodePtr, std::string>(nullptr, "");
58+
}
59+
std::tuple<std::string, StructNodePtr, std::string> StructNode::findNameSpace(
60+
const std::string &content)
61+
{
62+
LOG_DEBUG << "findNameSpace";
63+
if (content.empty())
64+
return std::tuple<std::string, StructNodePtr, std::string>("",
65+
nullptr,
66+
"");
67+
std::regex rx(R"(namespace[ \r\n]+([^ \r\n]+)[ \r\n]*\{)");
68+
std::smatch results;
69+
if (std::regex_search(content, results, rx))
70+
{
71+
assert(results.size() > 1);
72+
auto pos = results.position();
73+
auto first = content.substr(0, pos);
74+
auto nextPart = findContentOfClassOrNameSpace(content, pos);
75+
auto npNodePtr = std::make_shared<StructNode>(nextPart.first,
76+
results[1].str(),
77+
kNameSpace);
78+
79+
return std::tuple<std::string, StructNodePtr, std::string>(
80+
first, npNodePtr, nextPart.second);
81+
}
82+
else
83+
{
84+
return std::tuple<std::string, StructNodePtr, std::string>("",
85+
nullptr,
86+
"");
87+
}
88+
}
89+
std::vector<StructNodePtr> StructNode::parse(const std::string &content)
90+
{
91+
std::vector<StructNodePtr> res;
92+
auto t = findNameSpace(content);
93+
if (std::get<1>(t))
94+
{
95+
res.emplace_back(std::get<1>(t));
96+
auto firstPart = std::get<0>(t);
97+
while (1)
98+
{
99+
auto p = findClass(firstPart);
100+
if (p.first)
101+
{
102+
res.emplace_back(p.first);
103+
firstPart = p.second;
104+
}
105+
else
106+
{
107+
break;
108+
}
109+
}
110+
auto subsequentNode = parse(std::get<2>(t));
111+
for (auto &node : subsequentNode)
112+
{
113+
res.emplace_back(node);
114+
}
115+
return res;
116+
}
117+
std::string classPart = content;
118+
while (1)
119+
{
120+
auto p = findClass(classPart);
121+
if (p.first)
122+
{
123+
res.emplace_back(p.first);
124+
classPart = p.second;
125+
}
126+
else
127+
{
128+
break;
129+
}
130+
}
131+
return res;
132+
}
133+
void StructNode::print(int indent) const
134+
{
135+
std::string ind(indent, ' ');
136+
std::cout << ind;
137+
switch (type_)
138+
{
139+
case kRoot:
140+
{
141+
std::cout << "Root\n" << ind << "{\n";
142+
break;
143+
}
144+
case kClass:
145+
{
146+
std::cout << "class " << name_ << "\n" << ind << "{\n";
147+
break;
148+
}
149+
case kNameSpace:
150+
{
151+
std::cout << "namespace " << name_ << "\n" << ind << "{\n";
152+
break;
153+
}
154+
}
155+
156+
for (auto child : children_)
157+
{
158+
child->print(indent + 2);
159+
}
160+
if (type_ == kClass)
161+
{
162+
std::cout << content_ << "\n";
163+
}
164+
std::cout << ind << "}";
165+
if (type_ == kClass)
166+
std::cout << ";";
167+
std::cout << "\n";
168+
}

drogon_ctl/HandlerParser.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#pragma once
2+
#include <drogon/HttpTypes.h>
3+
#include <trantor/utils/Logger.h>
4+
#include <vector>
5+
#include <memory>
6+
#include <string>
7+
#include <tuple>
8+
9+
namespace drogon
10+
{
11+
namespace internal
12+
{
13+
class StructNode;
14+
using StructNodePtr = std::shared_ptr<StructNode>;
15+
class StructNode
16+
{
17+
public:
18+
enum NodeType
19+
{
20+
kRoot = 0,
21+
kClass,
22+
kNameSpace
23+
};
24+
25+
StructNode(const std::string &content,
26+
const std::string &name,
27+
NodeType type = kRoot)
28+
: type_(type), name_(name), content_(content)
29+
{
30+
LOG_DEBUG << "new node:" << name << "-" << type;
31+
if (type != kClass)
32+
children_ = parse(content);
33+
}
34+
const std::string &content() const
35+
{
36+
return content_;
37+
}
38+
const std::string &name() const
39+
{
40+
return name_;
41+
}
42+
NodeType type() const
43+
{
44+
return type_;
45+
}
46+
void print() const
47+
{
48+
print(0);
49+
}
50+
51+
private:
52+
std::vector<StructNodePtr> children_;
53+
std::string content_;
54+
NodeType type_;
55+
std::string name_;
56+
std::pair<std::string, std::string> findContentOfClassOrNameSpace(
57+
const std::string &content,
58+
std::string::size_type start);
59+
std::pair<StructNodePtr, std::string> findClass(const std::string &content);
60+
std::tuple<std::string, StructNodePtr, std::string> findNameSpace(
61+
const std::string &content);
62+
std::vector<StructNodePtr> parse(const std::string &content);
63+
void print(int indent) const;
64+
};
65+
66+
class ParametersInfo
67+
{
68+
public:
69+
std::string getName() const;
70+
std::string getType() const;
71+
std::string getConstraint() const;
72+
};
73+
class RoutingInfo
74+
{
75+
public:
76+
std::string getPath() const;
77+
std::vector<std::string> getFilters() const;
78+
std::vector<drogon::HttpMethod> getHttpMethods() const;
79+
std::string getScripts() const;
80+
std::string getContentType() const;
81+
std::string getReturnContentType() const;
82+
std::vector<ParametersInfo> getParameterInfo() const;
83+
std::vector<ParametersInfo> getReturnParameterInfo() const;
84+
};
85+
86+
class HandlerInfo
87+
{
88+
public:
89+
std::string getClassName() const;
90+
std::string getNamespace() const;
91+
std::vector<RoutingInfo> getRoutingInfo() const;
92+
};
93+
class HandlerParser
94+
{
95+
public:
96+
std::vector<HandlerInfo> parse();
97+
HandlerParser(const StructNodePtr root);
98+
};
99+
} // namespace internal
100+
} // namespace drogon

0 commit comments

Comments
 (0)