Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
e4579db6
Unverified
Commit
e4579db6
authored
Jan 16, 2020
by
Dennis Jenkins
Committed by
GitHub
Jan 16, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #661 from dennisjenkins75/master
Reformatted with 'clang-format' with default options.
parents
c7e9ac4c
2447ef55
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
286 additions
and
361 deletions
+286
-361
src/common/description.cc
src/common/description.cc
+286
-361
No files found.
src/common/description.cc
View file @
e4579db6
/* description.cc
Mathieu Stefani, 24 février 2016
Implementation of the description system
*/
...
...
@@ -8,482 +8,407 @@
#include <pistache/description.h>
#include <pistache/http_header.h>
#include <sstream>
#include <algorithm>
#include <sstream>
namespace
Pistache
{
namespace
Rest
{
const
char
*
schemeString
(
Scheme
scheme
)
{
switch
(
scheme
)
{
#define SCHEME(e, str) \
case Scheme::e:
\
return str;
SCHEMES
const
char
*
schemeString
(
Scheme
scheme
)
{
switch
(
scheme
)
{
#define SCHEME(e, str)
\
case Scheme::e:
\
return str;
SCHEMES
#undef SCHEME
}
}
return
nullptr
;
return
nullptr
;
}
namespace
Schema
{
Contact
::
Contact
(
std
::
string
name
,
std
::
string
url
,
std
::
string
email
)
:
name
(
std
::
move
(
name
))
,
url
(
std
::
move
(
url
))
,
email
(
std
::
move
(
email
))
{
}
License
::
License
(
std
::
string
name
,
std
::
string
url
)
:
name
(
std
::
move
(
name
))
,
url
(
std
::
move
(
url
))
{
}
Info
::
Info
(
std
::
string
title
,
std
::
string
version
,
std
::
string
description
)
:
title
(
std
::
move
(
title
))
,
version
(
std
::
move
(
version
))
,
description
(
std
::
move
(
description
))
,
termsOfService
()
,
contact
()
,
license
()
{
}
PathDecl
::
PathDecl
(
std
::
string
value
,
Http
::
Method
method
)
:
value
(
std
::
move
(
value
))
,
method
(
method
)
{
}
Contact
::
Contact
(
std
::
string
name
,
std
::
string
url
,
std
::
string
email
)
:
name
(
std
::
move
(
name
)),
url
(
std
::
move
(
url
)),
email
(
std
::
move
(
email
))
{}
Path
::
Path
(
std
::
string
value
,
Http
::
Method
method
,
std
::
string
description
)
:
value
(
std
::
move
(
value
))
,
method
(
method
)
,
description
(
std
::
move
(
description
))
,
hidden
(
false
)
,
pc
()
,
parameters
()
,
responses
()
,
handler
()
{
}
std
::
string
Path
::
swaggerFormat
(
const
std
::
string
&
path
)
{
if
(
path
.
empty
())
return
""
;
if
(
path
[
0
]
!=
'/'
)
throw
std
::
invalid_argument
(
"Invalid path, should start with a '/'"
);
/* @CodeDup: re-use the private Fragment class of Router */
auto
isPositional
=
[](
const
std
::
string
&
fragment
)
{
if
(
fragment
[
0
]
==
':'
)
return
std
::
make_pair
(
true
,
fragment
.
substr
(
1
));
return
std
::
make_pair
(
false
,
std
::
string
());
};
auto
isOptional
=
[](
const
std
::
string
&
fragment
)
{
auto
pos
=
fragment
.
find
(
'?'
);
// @Validation the '?' should be the last character
return
std
::
make_pair
(
pos
!=
std
::
string
::
npos
,
pos
);
};
License
::
License
(
std
::
string
name
,
std
::
string
url
)
:
name
(
std
::
move
(
name
)),
url
(
std
::
move
(
url
))
{}
std
::
ostringstream
oss
;
Info
::
Info
(
std
::
string
title
,
std
::
string
version
,
std
::
string
description
)
:
title
(
std
::
move
(
title
)),
version
(
std
::
move
(
version
)),
description
(
std
::
move
(
description
)),
termsOfService
(),
contact
(),
license
()
{}
auto
processFragment
=
[
&
](
std
::
string
fragment
)
{
auto
optional
=
isOptional
(
fragment
);
if
(
optional
.
first
)
fragment
.
erase
(
optional
.
second
,
1
);
PathDecl
::
PathDecl
(
std
::
string
value
,
Http
::
Method
method
)
:
value
(
std
::
move
(
value
)),
method
(
method
)
{}
auto
positional
=
isPositional
(
fragment
);
if
(
positional
.
first
)
{
oss
<<
'{'
<<
positional
.
second
<<
'}'
;
}
else
{
oss
<<
fragment
;
}
};
Path
::
Path
(
std
::
string
value
,
Http
::
Method
method
,
std
::
string
description
)
:
value
(
std
::
move
(
value
)),
method
(
method
),
description
(
std
::
move
(
description
)),
hidden
(
false
),
pc
(),
parameters
(),
responses
(),
handler
()
{}
std
::
string
Path
::
swaggerFormat
(
const
std
::
string
&
path
)
{
if
(
path
.
empty
())
return
""
;
if
(
path
[
0
]
!=
'/'
)
throw
std
::
invalid_argument
(
"Invalid path, should start with a '/'"
);
/* @CodeDup: re-use the private Fragment class of Router */
auto
isPositional
=
[](
const
std
::
string
&
fragment
)
{
if
(
fragment
[
0
]
==
':'
)
return
std
::
make_pair
(
true
,
fragment
.
substr
(
1
));
return
std
::
make_pair
(
false
,
std
::
string
());
};
auto
isOptional
=
[](
const
std
::
string
&
fragment
)
{
auto
pos
=
fragment
.
find
(
'?'
);
// @Validation the '?' should be the last character
return
std
::
make_pair
(
pos
!=
std
::
string
::
npos
,
pos
);
};
std
::
ostringstream
oss
;
auto
processFragment
=
[
&
](
std
::
string
fragment
)
{
auto
optional
=
isOptional
(
fragment
);
if
(
optional
.
first
)
fragment
.
erase
(
optional
.
second
,
1
);
auto
positional
=
isPositional
(
fragment
);
if
(
positional
.
first
)
{
oss
<<
'{'
<<
positional
.
second
<<
'}'
;
}
else
{
oss
<<
fragment
;
}
};
std
::
istringstream
iss
(
path
);
std
::
string
fragment
;
std
::
istringstream
iss
(
path
);
std
::
string
fragment
;
std
::
vector
<
std
::
string
>
fragments
;
std
::
vector
<
std
::
string
>
fragments
;
while
(
std
::
getline
(
iss
,
fragment
,
'/'
))
{
fragments
.
push_back
(
std
::
move
(
fragment
));
}
while
(
std
::
getline
(
iss
,
fragment
,
'/'
))
{
fragments
.
push_back
(
std
::
move
(
fragment
));
}
for
(
size_t
i
=
0
;
i
<
fragments
.
size
()
-
1
;
++
i
)
{
const
auto
&
frag
=
fragments
[
i
];
for
(
size_t
i
=
0
;
i
<
fragments
.
size
()
-
1
;
++
i
)
{
const
auto
&
frag
=
fragments
[
i
];
processFragment
(
frag
);
oss
<<
'/'
;
}
processFragment
(
frag
);
oss
<<
'/'
;
}
const
auto
&
last
=
fragments
.
back
();
if
(
last
.
empty
())
oss
<<
'/'
;
else
{
processFragment
(
last
);
}
const
auto
&
last
=
fragments
.
back
();
if
(
last
.
empty
())
oss
<<
'/'
;
else
{
processFragment
(
last
);
}
return
oss
.
str
();
return
oss
.
str
();
}
bool
PathGroup
::
hasPath
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
{
auto
group
=
paths
(
name
);
auto
it
=
std
::
find_if
(
std
::
begin
(
group
),
std
::
end
(
group
),
[
&
](
const
Path
&
p
)
{
return
p
.
method
==
method
;
});
return
it
!=
std
::
end
(
group
);
bool
PathGroup
::
hasPath
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
{
auto
group
=
paths
(
name
);
auto
it
=
std
::
find_if
(
std
::
begin
(
group
),
std
::
end
(
group
),
[
&
](
const
Path
&
p
)
{
return
p
.
method
==
method
;
});
return
it
!=
std
::
end
(
group
);
}
bool
PathGroup
::
hasPath
(
const
Path
&
path
)
const
{
return
hasPath
(
path
.
value
,
path
.
method
);
bool
PathGroup
::
hasPath
(
const
Path
&
path
)
const
{
return
hasPath
(
path
.
value
,
path
.
method
);
}
PathGroup
::
Group
PathGroup
::
paths
(
const
std
::
string
&
name
)
const
{
auto
it
=
groups_
.
find
(
name
);
if
(
it
==
std
::
end
(
groups_
))
return
PathGroup
::
Group
{
};
PathGroup
::
Group
PathGroup
::
paths
(
const
std
::
string
&
name
)
const
{
auto
it
=
groups_
.
find
(
name
);
if
(
it
==
std
::
end
(
groups_
))
return
PathGroup
::
Group
{};
return
it
->
second
;
return
it
->
second
;
}
Optional
<
Path
>
PathGroup
::
path
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
{
auto
group
=
paths
(
name
);
auto
it
=
std
::
find_if
(
std
::
begin
(
group
),
std
::
end
(
group
),
[
&
](
const
Path
&
p
)
{
return
p
.
method
==
method
;
});
Optional
<
Path
>
PathGroup
::
path
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
{
auto
group
=
paths
(
name
);
auto
it
=
std
::
find_if
(
std
::
begin
(
group
),
std
::
end
(
group
),
[
&
](
const
Path
&
p
)
{
return
p
.
method
==
method
;
});
if
(
it
!=
std
::
end
(
group
))
{
return
Optional
<
Path
>
(
Some
(
*
it
));
}
return
Optional
<
Path
>
(
None
());
if
(
it
!=
std
::
end
(
group
))
{
return
Optional
<
Path
>
(
Some
(
*
it
));
}
return
Optional
<
Path
>
(
None
());
}
PathGroup
::
group_iterator
PathGroup
::
add
(
Path
path
)
{
if
(
hasPath
(
path
))
return
PathGroup
::
group_iterator
{
};
PathGroup
::
group_iterator
PathGroup
::
add
(
Path
path
)
{
if
(
hasPath
(
path
))
return
PathGroup
::
group_iterator
{};
auto
&
group
=
groups_
[
path
.
value
];
return
group
.
insert
(
group
.
end
(),
std
::
move
(
path
));
auto
&
group
=
groups_
[
path
.
value
];
return
group
.
insert
(
group
.
end
(),
std
::
move
(
path
));
}
PathGroup
::
const_iterator
PathGroup
::
begin
()
const
{
return
groups_
.
begin
();
}
PathGroup
::
const_iterator
PathGroup
::
begin
()
const
{
return
groups_
.
begin
();
}
PathGroup
::
const_iterator
PathGroup
::
end
()
const
{
return
groups_
.
end
();
}
PathGroup
::
const_iterator
PathGroup
::
end
()
const
{
return
groups_
.
end
();
}
PathGroup
::
flat_iterator
PathGroup
::
flatBegin
()
const
{
return
makeFlatMapIterator
(
groups_
,
begin
());
PathGroup
::
flat_iterator
PathGroup
::
flatBegin
()
const
{
return
makeFlatMapIterator
(
groups_
,
begin
());
}
PathGroup
::
flat_iterator
PathGroup
::
flatEnd
()
const
{
return
makeFlatMapIterator
(
groups_
,
end
());
PathGroup
::
flat_iterator
PathGroup
::
flatEnd
()
const
{
return
makeFlatMapIterator
(
groups_
,
end
());
}
PathBuilder
::
PathBuilder
(
Path
*
path
)
:
path_
(
path
)
{
}
PathBuilder
::
PathBuilder
(
Path
*
path
)
:
path_
(
path
)
{}
SubPath
::
SubPath
(
std
::
string
prefix
,
PathGroup
*
paths
)
:
prefix
(
std
::
move
(
prefix
))
,
parameters
()
,
paths
(
paths
)
{
}
SubPath
::
SubPath
(
std
::
string
prefix
,
PathGroup
*
paths
)
:
prefix
(
std
::
move
(
prefix
)),
parameters
(),
paths
(
paths
)
{}
PathBuilder
SubPath
::
route
(
const
std
::
string
&
name
,
Http
::
Method
method
,
std
::
string
description
)
{
auto
fullPath
=
prefix
+
name
;
Path
path
(
std
::
move
(
fullPath
),
method
,
std
::
move
(
description
));
std
::
copy
(
std
::
begin
(
parameters
),
std
::
end
(
parameters
),
std
::
back_inserter
(
path
.
parameters
));
PathBuilder
SubPath
::
route
(
const
std
::
string
&
name
,
Http
::
Method
method
,
std
::
string
description
)
{
auto
fullPath
=
prefix
+
name
;
Path
path
(
std
::
move
(
fullPath
),
method
,
std
::
move
(
description
));
std
::
copy
(
std
::
begin
(
parameters
),
std
::
end
(
parameters
),
std
::
back_inserter
(
path
.
parameters
));
auto
it
=
paths
->
add
(
std
::
move
(
path
));
auto
it
=
paths
->
add
(
std
::
move
(
path
));
return
PathBuilder
(
&*
it
);
return
PathBuilder
(
&*
it
);
}
PathBuilder
SubPath
::
route
(
PathDecl
fragment
,
std
::
string
description
)
{
return
route
(
std
::
move
(
fragment
.
value
),
fragment
.
method
,
std
::
move
(
description
));
PathBuilder
SubPath
::
route
(
PathDecl
fragment
,
std
::
string
description
)
{
return
route
(
std
::
move
(
fragment
.
value
),
fragment
.
method
,
std
::
move
(
description
));
}
SubPath
SubPath
::
path
(
const
std
::
string
&
prefix
)
{
return
SubPath
(
this
->
prefix
+
prefix
,
paths
);
SubPath
SubPath
::
path
(
const
std
::
string
&
prefix
)
{
return
SubPath
(
this
->
prefix
+
prefix
,
paths
);
}
Parameter
::
Parameter
(
std
::
string
name
,
std
::
string
description
)
:
name
(
std
::
move
(
name
))
,
description
(
std
::
move
(
description
))
,
required
(
true
)
,
type
()
{
}
Parameter
::
Parameter
(
std
::
string
name
,
std
::
string
description
)
:
name
(
std
::
move
(
name
)),
description
(
std
::
move
(
description
)),
required
(
true
),
type
()
{}
Response
::
Response
(
Http
::
Code
statusCode
,
std
::
string
description
)
:
statusCode
(
statusCode
)
,
description
(
std
::
move
(
description
))
{
}
Response
::
Response
(
Http
::
Code
statusCode
,
std
::
string
description
)
:
statusCode
(
statusCode
),
description
(
std
::
move
(
description
))
{}
ResponseBuilder
::
ResponseBuilder
(
Http
::
Code
statusCode
,
std
::
string
description
)
:
response_
(
statusCode
,
std
::
move
(
description
))
{
}
ResponseBuilder
::
ResponseBuilder
(
Http
::
Code
statusCode
,
std
::
string
description
)
:
response_
(
statusCode
,
std
::
move
(
description
))
{}
InfoBuilder
::
InfoBuilder
(
Info
*
info
)
:
info_
(
info
)
{
}
InfoBuilder
::
InfoBuilder
(
Info
*
info
)
:
info_
(
info
)
{}
InfoBuilder
&
InfoBuilder
::
termsOfService
(
std
::
string
value
)
{
info_
->
termsOfService
=
std
::
move
(
value
);
return
*
this
;
InfoBuilder
&
InfoBuilder
::
termsOfService
(
std
::
string
value
)
{
info_
->
termsOfService
=
std
::
move
(
value
);
return
*
this
;
}
InfoBuilder
&
InfoBuilder
::
contact
(
std
::
string
name
,
std
::
string
url
,
std
::
string
email
)
{
info_
->
contact
=
Some
(
Contact
(
std
::
move
(
name
),
std
::
move
(
url
),
std
::
move
(
email
)));
return
*
this
;
InfoBuilder
&
InfoBuilder
::
contact
(
std
::
string
name
,
std
::
string
url
,
std
::
string
email
)
{
info_
->
contact
=
Some
(
Contact
(
std
::
move
(
name
),
std
::
move
(
url
),
std
::
move
(
email
)));
return
*
this
;
}
InfoBuilder
&
InfoBuilder
::
license
(
std
::
string
name
,
std
::
string
url
)
{
info_
->
license
=
Some
(
License
(
std
::
move
(
name
),
std
::
move
(
url
)));
return
*
this
;
InfoBuilder
&
InfoBuilder
::
license
(
std
::
string
name
,
std
::
string
url
)
{
info_
->
license
=
Some
(
License
(
std
::
move
(
name
),
std
::
move
(
url
)));
return
*
this
;
}
}
// namespace Schema
Description
::
Description
(
std
::
string
title
,
std
::
string
version
,
std
::
string
description
)
:
info_
(
std
::
move
(
title
),
std
::
move
(
version
),
std
::
move
(
description
))
,
host_
()
,
basePath_
()
,
schemes_
()
,
pc
()
,
paths_
()
{
}
Description
::
Description
(
std
::
string
title
,
std
::
string
version
,
std
::
string
description
)
:
info_
(
std
::
move
(
title
),
std
::
move
(
version
),
std
::
move
(
description
)),
host_
(),
basePath_
(),
schemes_
(),
pc
(),
paths_
()
{}
Schema
::
InfoBuilder
Description
::
info
()
{
Schema
::
InfoBuilder
builder
(
&
info_
);
return
builder
;
Schema
::
InfoBuilder
Description
::
info
()
{
Schema
::
InfoBuilder
builder
(
&
info_
);
return
builder
;
}
Description
&
Description
::
host
(
std
::
string
value
)
{
host_
=
std
::
move
(
value
);
return
*
this
;
Description
&
Description
::
host
(
std
::
string
value
)
{
host_
=
std
::
move
(
value
);
return
*
this
;
}
Description
&
Description
::
basePath
(
std
::
string
value
)
{
basePath_
=
std
::
move
(
value
);
return
*
this
;
Description
&
Description
::
basePath
(
std
::
string
value
)
{
basePath_
=
std
::
move
(
value
);
return
*
this
;
}
Schema
::
PathDecl
Description
::
options
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Options
);
Schema
::
PathDecl
Description
::
options
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Options
);
}
Schema
::
PathDecl
Description
::
get
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Get
);
Schema
::
PathDecl
Description
::
get
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Get
);
}
Schema
::
PathDecl
Description
::
post
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Post
);
Schema
::
PathDecl
Description
::
post
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Post
);
}
Schema
::
PathDecl
Description
::
head
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Head
);
Schema
::
PathDecl
Description
::
head
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Head
);
}
Schema
::
PathDecl
Description
::
put
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Put
);
Schema
::
PathDecl
Description
::
put
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Put
);
}
Schema
::
PathDecl
Description
::
patch
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Patch
);
Schema
::
PathDecl
Description
::
patch
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Patch
);
}
Schema
::
PathDecl
Description
::
del
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Delete
);
Schema
::
PathDecl
Description
::
del
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Delete
);
}
Schema
::
PathDecl
Description
::
trace
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Trace
);
Schema
::
PathDecl
Description
::
trace
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Trace
);
}
Schema
::
PathDecl
Description
::
connect
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Connect
);
Schema
::
PathDecl
Description
::
connect
(
std
::
string
name
)
{
return
Schema
::
PathDecl
(
std
::
move
(
name
),
Http
::
Method
::
Connect
);
}
Schema
::
SubPath
Description
::
path
(
std
::
string
name
)
{
return
Schema
::
SubPath
(
std
::
move
(
name
),
&
paths_
);
Schema
::
SubPath
Description
::
path
(
std
::
string
name
)
{
return
Schema
::
SubPath
(
std
::
move
(
name
),
&
paths_
);
}
Schema
::
PathBuilder
Description
::
route
(
std
::
string
name
,
Http
::
Method
method
,
std
::
string
description
)
{
auto
it
=
paths_
.
emplace
(
std
::
move
(
name
),
method
,
std
::
move
(
description
));
return
Schema
::
PathBuilder
(
&*
it
);
Schema
::
PathBuilder
Description
::
route
(
std
::
string
name
,
Http
::
Method
method
,
std
::
string
description
)
{
auto
it
=
paths_
.
emplace
(
std
::
move
(
name
),
method
,
std
::
move
(
description
));
return
Schema
::
PathBuilder
(
&*
it
);
}
Schema
::
PathBuilder
Description
::
route
(
Schema
::
PathDecl
fragment
,
std
::
string
description
)
{
return
route
(
std
::
move
(
fragment
.
value
),
fragment
.
method
,
std
::
move
(
description
));
Schema
::
PathBuilder
Description
::
route
(
Schema
::
PathDecl
fragment
,
std
::
string
description
)
{
return
route
(
std
::
move
(
fragment
.
value
),
fragment
.
method
,
std
::
move
(
description
));
}
Schema
::
ResponseBuilder
Description
::
response
(
Http
::
Code
statusCode
,
std
::
string
description
)
{
Schema
::
ResponseBuilder
builder
(
statusCode
,
std
::
move
(
description
));
return
builder
;
Schema
::
ResponseBuilder
Description
::
response
(
Http
::
Code
statusCode
,
std
::
string
description
)
{
Schema
::
ResponseBuilder
builder
(
statusCode
,
std
::
move
(
description
));
return
builder
;
}
Swagger
&
Swagger
::
uiPath
(
std
::
string
path
)
{
uiPath_
=
std
::
move
(
path
);
return
*
this
;
Swagger
&
Swagger
::
uiPath
(
std
::
string
path
)
{
uiPath_
=
std
::
move
(
path
);
return
*
this
;
}
Swagger
&
Swagger
::
uiDirectory
(
std
::
string
dir
)
{
uiDirectory_
=
std
::
move
(
dir
);
return
*
this
;
Swagger
&
Swagger
::
uiDirectory
(
std
::
string
dir
)
{
uiDirectory_
=
std
::
move
(
dir
);
return
*
this
;
}
Swagger
&
Swagger
::
apiPath
(
std
::
string
path
)
{
apiPath_
=
std
::
move
(
path
);
return
*
this
;
Swagger
&
Swagger
::
apiPath
(
std
::
string
path
)
{
apiPath_
=
std
::
move
(
path
);
return
*
this
;
}
Swagger
&
Swagger
::
serializer
(
Swagger
::
Serializer
serialize
)
{
serializer_
=
std
::
move
(
serialize
);
return
*
this
;
Swagger
&
Swagger
::
serializer
(
Swagger
::
Serializer
serialize
)
{
serializer_
=
std
::
move
(
serialize
);
return
*
this
;
}
void
Swagger
::
install
(
Rest
::
Router
&
router
)
{
Route
::
Handler
uiHandler
=
[
=
](
const
Rest
::
Request
&
req
,
Http
::
ResponseWriter
response
)
{
auto
res
=
req
.
resource
();
/*
* @Export might be useful for routing also. Make it public or merge it with the Fragment class
*/
struct
Path
{
explicit
Path
(
const
std
::
string
&
value
)
:
value
(
value
)
,
trailingSlashValue
(
value
)
{
if
(
trailingSlashValue
.
empty
()
||
trailingSlashValue
.
back
()
!=
'/'
)
trailingSlashValue
+=
'/'
;
}
static
bool
hasTrailingSlash
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
();
return
res_
.
back
()
==
'/'
;
}
std
::
string
stripPrefix
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
();
if
(
!
res_
.
compare
(
0
,
value
.
size
(),
value
))
{
return
res_
.
substr
(
value
.
size
());
}
return
res_
;
}
bool
matches
(
const
Rest
::
Request
&
req
)
const
{
auto
res_
=
req
.
resource
();
if
(
value
==
res_
)
return
true
;
if
(
res_
==
trailingSlashValue
)
return
true
;
return
false
;
}
void
Swagger
::
install
(
Rest
::
Router
&
router
)
{
bool
isPrefix
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
();
return
!
res_
.
compare
(
0
,
value
.
size
(),
value
);
}
Route
::
Handler
uiHandler
=
[
=
](
const
Rest
::
Request
&
req
,
Http
::
ResponseWriter
response
)
{
auto
res
=
req
.
resource
();
const
std
::
string
&
withTrailingSlash
()
const
{
return
trailingSlashValue
;
}
/*
* @Export might be useful for routing also. Make it public or merge it with
* the Fragment class
*/
std
::
string
join
(
const
std
::
string
&
value
)
const
{
std
::
string
val
;
if
(
value
[
0
]
==
'/'
)
val
=
value
.
substr
(
1
);
else
val
=
value
;
return
trailingSlashValue
+
val
;
}
struct
Path
{
explicit
Path
(
const
std
::
string
&
value
)
:
value
(
value
),
trailingSlashValue
(
value
)
{
if
(
trailingSlashValue
.
empty
()
||
trailingSlashValue
.
back
()
!=
'/'
)
trailingSlashValue
+=
'/'
;
}
private:
std
::
string
value
;
std
::
string
trailingSlashValue
;
};
static
bool
hasTrailingSlash
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
()
;
return
res_
.
back
()
==
'/'
;
}
Path
ui
(
uiPath_
);
Path
uiDir
(
uiDirectory_
);
if
(
ui
.
matches
(
req
))
{
if
(
!
Path
::
hasTrailingSlash
(
req
))
{
response
.
headers
()
.
add
<
Http
::
Header
::
Location
>
(
uiPath_
+
'/'
);
response
.
send
(
Http
::
Code
::
Moved_Permanently
);
}
else
{
auto
index
=
uiDir
.
join
(
"index.html"
);
Http
::
serveFile
(
response
,
index
);
}
return
Route
::
Result
::
Ok
;
}
else
if
(
ui
.
isPrefix
(
req
))
{
auto
file
=
ui
.
stripPrefix
(
req
);
auto
path
=
uiDir
.
join
(
file
);
Http
::
serveFile
(
response
,
path
);
return
Route
::
Result
::
Ok
;
std
::
string
stripPrefix
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
();
if
(
!
res_
.
compare
(
0
,
value
.
size
(),
value
))
{
return
res_
.
substr
(
value
.
size
());
}
return
res_
;
}
bool
matches
(
const
Rest
::
Request
&
req
)
const
{
auto
res_
=
req
.
resource
();
if
(
value
==
res_
)
return
true
;
if
(
res_
==
trailingSlashValue
)
return
true
;
return
false
;
}
bool
isPrefix
(
const
Rest
::
Request
&
req
)
{
auto
res_
=
req
.
resource
();
return
!
res_
.
compare
(
0
,
value
.
size
(),
value
);
}
const
std
::
string
&
withTrailingSlash
()
const
{
return
trailingSlashValue
;
}
std
::
string
join
(
const
std
::
string
&
value
)
const
{
std
::
string
val
;
if
(
value
[
0
]
==
'/'
)
val
=
value
.
substr
(
1
);
else
val
=
value
;
return
trailingSlashValue
+
val
;
}
private:
std
::
string
value
;
std
::
string
trailingSlashValue
;
};
else
if
(
res
==
apiPath_
)
{
response
.
send
(
Http
::
Code
::
Ok
,
serializer_
(
description_
),
MIME
(
Application
,
Json
));
return
Route
::
Result
::
Ok
;
}
Path
ui
(
uiPath_
);
Path
uiDir
(
uiDirectory_
);
if
(
ui
.
matches
(
req
))
{
if
(
!
Path
::
hasTrailingSlash
(
req
))
{
response
.
headers
().
add
<
Http
::
Header
::
Location
>
(
uiPath_
+
'/'
);
response
.
send
(
Http
::
Code
::
Moved_Permanently
);
}
else
{
auto
index
=
uiDir
.
join
(
"index.html"
);
Http
::
serveFile
(
response
,
index
);
}
return
Route
::
Result
::
Ok
;
}
else
if
(
ui
.
isPrefix
(
req
))
{
auto
file
=
ui
.
stripPrefix
(
req
);
auto
path
=
uiDir
.
join
(
file
);
Http
::
serveFile
(
response
,
path
);
return
Route
::
Result
::
Ok
;
}
return
Route
::
Result
::
Failure
;
};
else
if
(
res
==
apiPath_
)
{
response
.
send
(
Http
::
Code
::
Ok
,
serializer_
(
description_
),
MIME
(
Application
,
Json
));
return
Route
::
Result
::
Ok
;
}
r
outer
.
addCustomHandler
(
uiHandler
)
;
}
r
eturn
Route
::
Result
::
Failure
;
};
router
.
addCustomHandler
(
uiHandler
);
}
}
// namespace Rest
}
// namespace Pistache
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment