Sourcemeta Core 0.0.0
Loading...
Searching...
No Matches
openapi.h
1#ifndef SOURCEMETA_CORE_OPENAPI_H_
2#define SOURCEMETA_CORE_OPENAPI_H_
3
4#ifndef SOURCEMETA_CORE_OPENAPI_EXPORT
5#include <sourcemeta/core/openapi_export.h>
6#endif
7
8#include <sourcemeta/core/json.h>
9#include <sourcemeta/core/jsonpointer.h>
10#include <sourcemeta/core/jsonschema.h>
11
12// NOLINTBEGIN(misc-include-cleaner)
13#include <sourcemeta/core/openapi_error.h>
14// NOLINTEND(misc-include-cleaner)
15
16#include <concepts> // std::invocable, std::predicate
17#include <cstddef> // std::size_t
18#include <cstdint> // std::uint8_t, std::uint64_t
19#include <functional> // std::function, std::less
20#include <limits> // std::numeric_limits
21#include <map> // std::map
22#include <memory> // std::unique_ptr
23#include <optional> // std::optional, std::nullopt
24#include <string_view> // std::string_view
25#include <vector> // std::vector
26
38
39namespace sourcemeta::core {
40
43enum class OpenAPIVersion : std::uint8_t {
48};
49
71SOURCEMETA_CORE_OPENAPI_EXPORT
72auto openapi_version(const JSON &document) -> std::optional<OpenAPIVersion>;
73
86SOURCEMETA_CORE_OPENAPI_EXPORT
87auto openapi_version_name(const OpenAPIVersion version) noexcept
89
96 std::optional<JSON::StringView> name{std::nullopt};
98 std::optional<JSON::StringView> url{std::nullopt};
100 std::optional<JSON::StringView> email{std::nullopt};
101};
102
112 std::optional<JSON::StringView> identifier{std::nullopt};
114 std::optional<JSON::StringView> url{std::nullopt};
115};
116
128 std::optional<JSON::StringView> summary{std::nullopt};
130 std::optional<JSON::StringView> description{std::nullopt};
132 std::optional<JSON::StringView> terms_of_service{std::nullopt};
134 std::optional<OpenAPIContact> contact{std::nullopt};
136 std::optional<OpenAPILicense> license{std::nullopt};
137};
138
167class SOURCEMETA_CORE_OPENAPI_EXPORT OpenAPIFrame {
168public:
175 enum class ObjectKind : std::uint8_t {
178 Document,
179 // The eleven a reference may expect to find, the last of them only from 3.2
180 // onwards, which is where a `content` map and the Components Object both
181 // learn to hold a Reference Object in place of a Media Type Object
183 PathItem,
185 Parameter,
187 RequestBody,
189 Response,
191 Example,
193 Header,
195 Link,
198 Callbacks,
200 SecurityScheme,
202 MediaType,
203 // The rest are never referenced, but every Object gets a location
205 Info,
207 Contact,
209 License,
211 Server,
214 ServerVariable,
216 Components,
218 Paths,
223 ExternalDocumentation,
226 Encoding,
228 Responses,
230 Tag,
235 Schema,
237 OAuthFlows,
239 OAuthFlow,
241 SecurityRequirement
242 };
243
249 enum class OperationKind : std::uint8_t {
251 Path,
253 Webhook,
255 Callback
256 };
257
280
283 struct Operation {
304 std::optional<JSON::String> parent{std::nullopt};
308 std::vector<JSON::String> servers;
310 std::vector<JSON::String> security;
314 std::vector<JSON::String> parameters;
319 std::vector<std::optional<JSON::String>> tags;
320 };
321
341
344 struct Location {
348 Pointer pointer;
353 std::optional<JSON::StringView> parent{std::nullopt};
366 };
367
371 using Locations = std::map<JSON::String, Location, std::less<>>;
372
375 using References = std::map<JSON::String, Reference, std::less<>>;
376
423 const JSON &document, const SchemaWalker &walker,
424 const SchemaResolver &resolver, std::string_view default_base = "",
425 std::uint64_t max_locations = std::numeric_limits<std::uint64_t>::max());
426
428
429 // We rely on internal caches that would be dangling otherwise
430 OpenAPIFrame(const OpenAPIFrame &) = delete;
431 auto operator=(const OpenAPIFrame &) -> OpenAPIFrame & = delete;
432 OpenAPIFrame(OpenAPIFrame &&) = delete;
433 auto operator=(OpenAPIFrame &&) -> OpenAPIFrame & = delete;
434
456 [[nodiscard]] auto version() const noexcept -> OpenAPIVersion;
457
479 [[nodiscard]] auto info() const noexcept -> const OpenAPIInfo &;
480
505 [[nodiscard]] auto base() const noexcept -> JSON::StringView;
506
529 [[nodiscard]] auto standalone() const noexcept -> bool;
530
556 [[nodiscard]] auto schemas() const noexcept -> const SchemaFrame &;
557
559 [[nodiscard]] auto locations() const noexcept -> const Locations &;
560
564 [[nodiscard]] auto references() const noexcept -> const References &;
565
571 [[nodiscard]] auto security_references() const noexcept -> const References &;
572
574 [[nodiscard]] auto operations() const noexcept
575 -> const std::vector<Operation> &;
576
579 [[nodiscard]] auto discriminators() const noexcept
580 -> const std::vector<Discriminator> &;
581
607 template <std::invocable<const JSON::String &, const Location &> F>
608 auto for_each_object(const F &callback) const -> void {
609 for (const auto &entry : this->locations()) {
610 callback(entry.first, entry.second);
611 }
612 }
613
637 template <std::predicate<const JSON::String &, const Location &> F>
638 [[nodiscard]] auto any_object(const F &predicate) const -> bool {
639 for (const auto &entry : this->locations()) {
640 if (predicate(entry.first, entry.second)) {
641 return true;
642 }
643 }
644
645 return false;
646 }
647
671 template <std::invocable<const JSON::String &, const Reference &> F>
672 auto for_each_reference(const F &callback) const -> void {
673 for (const auto &entry : this->references()) {
674 callback(entry.first, entry.second);
675 }
676 }
677
701 template <std::invocable<const JSON::String &, const Reference &> F>
702 auto for_each_security_reference(const F &callback) const -> void {
703 for (const auto &entry : this->security_references()) {
704 callback(entry.first, entry.second);
705 }
706 }
707
730 template <std::invocable<const Operation &> F>
731 auto for_each_operation(const F &callback) const -> void {
732 for (const auto &operation : this->operations()) {
733 callback(operation);
734 }
735 }
736
758 template <std::invocable<const Discriminator &> F>
759 auto for_each_discriminator(const F &callback) const -> void {
760 for (const auto &discriminator : this->discriminators()) {
761 callback(discriminator);
762 }
763 }
764
789 [[nodiscard]] auto traverse(const JSON::StringView uri) const
790 -> const Location *;
791
814 [[nodiscard]] auto uri(const Pointer &pointer) const -> JSON::String;
815
817 [[nodiscard]] auto object_count() const noexcept -> std::size_t;
818
821 [[nodiscard]] auto reference_count() const noexcept -> std::size_t;
822
851 [[nodiscard]] auto to_json(
852 const std::optional<PointerPositionTracker> &tracker = std::nullopt) const
853 -> JSON;
854
855private:
856// Exporting symbols that depends on the standard C++ library is considered
857// safe.
858// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
859#if defined(_MSC_VER)
860#pragma warning(push)
861#pragma warning(disable : 4251)
862#endif
863 struct Internal;
864 std::unique_ptr<Internal> internal_;
865#if defined(_MSC_VER)
866#pragma warning(pop)
867#endif
868};
869
882SOURCEMETA_CORE_OPENAPI_EXPORT
885
897SOURCEMETA_CORE_OPENAPI_EXPORT
899 const OpenAPIFrame::OperationKind kind) noexcept -> JSON::StringView;
900
905
930using OpenAPIResolver = std::function<OpenAPIResolverResult(std::string_view)>;
931
959SOURCEMETA_CORE_OPENAPI_EXPORT
960auto openapi_format(JSON &document, const OpenAPIFrame &frame) -> void;
961
969 using Callback =
970 std::function<void(JSON::StringView, const sourcemeta::core::Pointer &)>;
971
978
983 std::string_view default_base{};
998 std::uint64_t max_locations{std::numeric_limits<std::uint64_t>::max()};
1003};
1004
1056SOURCEMETA_CORE_OPENAPI_EXPORT
1057auto openapi_bundle(JSON &document, const SchemaWalker &walker,
1059 const OpenAPIResolver &resolver,
1060 const OpenAPIBundleOptions &options = {}) -> void;
1061
1109SOURCEMETA_CORE_OPENAPI_EXPORT
1110auto openapi_bundle(const JSON &document, const SchemaWalker &walker,
1112 const OpenAPIResolver &resolver,
1113 const OpenAPIBundleOptions &options = {}) -> JSON;
1114
1115} // namespace sourcemeta::core
1116
1117#endif
std::basic_string< Char, CharTraits, Allocator< Char > > String
The string type used by the JSON document.
Definition json_value.h:52
std::basic_string_view< Char, CharTraits > StringView
The string view type used by the JSON document.
Definition json_value.h:54
Definition json_value.h:39
Definition jsonpointer_position.h:51
GenericPointer< JSON::String, PropertyHashJSON< JSON::String > > Pointer
Definition jsonpointer.h:39
Definition jsonschema_frame.h:57
SOURCEMETA_CORE_JSONSCHEMA_EXPORT auto schema_resolver(const std::string_view identifier) -> SchemaResolverResult
std::function< SchemaResolverResult(std::string_view)> SchemaResolver
Definition jsonschema_types.h:41
std::function< const SchemaWalkerResult &( std::string_view, const SchemaVocabularies &)> SchemaWalker
Definition jsonschema_types.h:254
Definition memory_owned_or_reference.h:48
std::string_view default_base
Definition openapi.h:983
auto base() const noexcept -> JSON::StringView
std::optional< JSON::StringView > url
Where to find the contact information, as a URI reference.
Definition openapi.h:98
auto for_each_security_reference(const F &callback) const -> void
Definition openapi.h:702
std::optional< OpenAPIContact > contact
The contact information for the API.
Definition openapi.h:134
auto info() const noexcept -> const OpenAPIInfo &
auto schemas() const noexcept -> const SchemaFrame &
auto for_each_object(const F &callback) const -> void
Definition openapi.h:608
ObjectKind
Definition openapi.h:175
std::optional< JSON::StringView > summary
A short summary of the API.
Definition openapi.h:128
auto operations() const noexcept -> const std::vector< Operation > &
Every operation the described API exposes.
std::optional< OpenAPILicense > license
The license information for the API.
Definition openapi.h:136
auto for_each_discriminator(const F &callback) const -> void
Definition openapi.h:759
std::optional< JSON::StringView > url
Where to find the license used for the API, as a URI reference.
Definition openapi.h:114
JSON::StringView version
Definition openapi.h:126
Callback callback
A callback to report each place that bundling embedded.
Definition openapi.h:1000
auto locations() const noexcept -> const Locations &
Every Object the description holds, keyed by the URI addressing each one.
std::optional< JSON::StringView > name
The identifying name of the contact person or organisation.
Definition openapi.h:96
Namer namer
A callback to name each place that bundling embeds.
Definition openapi.h:1002
JSON::StringView name
The license name used for the API.
Definition openapi.h:109
std::uint64_t max_locations
Definition openapi.h:998
auto object_count() const noexcept -> std::size_t
How many Objects the description holds.
OpenAPIFrame(const JSON &document, const SchemaWalker &walker, const SchemaResolver &resolver, std::string_view default_base="", std::uint64_t max_locations=std::numeric_limits< std::uint64_t >::max())
auto discriminators() const noexcept -> const std::vector< Discriminator > &
auto for_each_operation(const F &callback) const -> void
Definition openapi.h:731
auto standalone() const noexcept -> bool
auto any_object(const F &predicate) const -> bool
Definition openapi.h:638
auto for_each_reference(const F &callback) const -> void
Definition openapi.h:672
auto references() const noexcept -> const References &
auto uri(const Pointer &pointer) const -> JSON::String
std::optional< JSON::StringView > identifier
Definition openapi.h:112
auto traverse(const JSON::StringView uri) const -> const Location *
auto security_references() const noexcept -> const References &
OperationKind
Definition openapi.h:249
std::optional< JSON::StringView > email
The email address of the contact person or organisation.
Definition openapi.h:100
auto reference_count() const noexcept -> std::size_t
std::map< JSON::String, Location, std::less<> > Locations
Definition openapi.h:371
std::function< JSON::String(JSON::StringView, JSON::StringView)> Namer
Definition openapi.h:977
std::optional< JSON::StringView > terms_of_service
Where to find the terms of service for the API, as a URI reference.
Definition openapi.h:132
auto version() const noexcept -> OpenAPIVersion
JSON::StringView title
The title of the API.
Definition openapi.h:123
std::map< JSON::String, Reference, std::less<> > References
Definition openapi.h:375
auto to_json(const std::optional< PointerPositionTracker > &tracker=std::nullopt) const -> JSON
std::optional< JSON::StringView > description
A description of the API, which may be written in CommonMark.
Definition openapi.h:130
std::function< void(JSON::StringView, const sourcemeta::core::Pointer &)> Callback
Definition openapi.h:969
Definition openapi.h:167
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_kind_name(const OpenAPIFrame::ObjectKind kind) noexcept -> JSON::StringView
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_operation_kind_name(const OpenAPIFrame::OperationKind kind) noexcept -> JSON::StringView
OwnedOrReference< JSON > OpenAPIResolverResult
Definition openapi.h:904
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_bundle(JSON &document, const SchemaWalker &walker, const SchemaResolver &schema_resolver, const OpenAPIResolver &resolver, const OpenAPIBundleOptions &options={}) -> void
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_version(const JSON &document) -> std::optional< OpenAPIVersion >
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_version_name(const OpenAPIVersion version) noexcept -> JSON::StringView
SOURCEMETA_CORE_OPENAPI_EXPORT auto openapi_format(JSON &document, const OpenAPIFrame &frame) -> void
OpenAPIVersion
Definition openapi.h:43
std::function< OpenAPIResolverResult(std::string_view)> OpenAPIResolver
Definition openapi.h:930
@ OPENAPI_3_2
The OpenAPI Specification 3.2 revision.
Definition openapi.h:47
@ OPENAPI_3_1
The OpenAPI Specification 3.1 revision.
Definition openapi.h:45
Definition openapi.h:94
Definition openapi.h:121
Definition openapi.h:107
Pointer origin
Where the mapping value sits, as a pointer from the root of the document.
Definition openapi.h:329
JSON::String destination
Where it points, resolved and canonicalised.
Definition openapi.h:331
JSON::String scope
Definition openapi.h:335
bool dangling
Definition openapi.h:339
JSON::String base
Definition openapi.h:365
ObjectKind type
What kind of Object sits here.
Definition openapi.h:346
std::optional< JSON::StringView > parent
Definition openapi.h:353
JSON::String default_dialect
Definition openapi.h:359
JSON::String method
The method it answers to, as the field that declares it is spelled.
Definition openapi.h:290
std::vector< JSON::String > security
Where the Security Requirement Objects in force sit.
Definition openapi.h:310
std::vector< JSON::String > parameters
Definition openapi.h:314
std::vector< std::optional< JSON::String > > tags
Definition openapi.h:319
JSON::String origin
Where the Operation Object sits.
Definition openapi.h:292
std::optional< JSON::String > parent
Definition openapi.h:304
JSON::String path
Definition openapi.h:288
JSON::String endpoint
Definition openapi.h:296
std::vector< JSON::String > servers
Definition openapi.h:308
OperationKind kind
How the entry document exposes it.
Definition openapi.h:285
bool dangling
Definition openapi.h:271
JSON::String original
The value as the document wrote it.
Definition openapi.h:264
Pointer origin
Definition openapi.h:278
ObjectKind expected
Definition openapi.h:275
JSON::String destination
Definition openapi.h:268