Skip to content

Commit 70df45e

Browse files
authored
Remove SchemaFlatFileResolver (#1689)
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 8ddd6f8 commit 70df45e

15 files changed

+2
-618
lines changed

src/core/jsonschema/include/sourcemeta/core/jsonschema_resolver.h

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <sourcemeta/core/json.h>
99
#include <sourcemeta/core/jsonschema_types.h>
1010

11-
#include <filesystem> // std::filesystem
1211
#include <functional> // std::function
1312
#include <map> // std::map
1413
#include <optional> // std::optional
@@ -74,85 +73,6 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaMapResolver {
7473
#endif
7574
};
7675

77-
/// @ingroup jsonschema
78-
/// A convenient dynamic schema resolver capable of storing a high number of
79-
/// schemas by deferencing them from disk on-demand. It is called a flat
80-
/// resolver as it only looks at the top-level identifier of every schema. For
81-
/// example:
82-
///
83-
/// ```cpp
84-
/// #include <sourcemeta/core/jsonschema.h>
85-
/// #include <cassert>
86-
///
87-
/// // (1) Create a flat file resolver that falls back to the official resolver
88-
/// sourcemeta::core::SchemaFlatFileResolver
89-
/// resolver{sourcemeta::core::schema_official_resolver};
90-
///
91-
/// // (2) Register a schema by path
92-
/// resolver.add("path/to/example.schema.json");
93-
///
94-
/// assert(resolver("https://www.example.com").has_value());
95-
/// ```
96-
class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFlatFileResolver {
97-
public:
98-
/// Construct an empty resolver. If you don't add schemas to it, it will
99-
/// always resolve to nothing
100-
SchemaFlatFileResolver();
101-
102-
/// Construct an empty resolver that has another schema resolver as a fallback
103-
SchemaFlatFileResolver(const SchemaResolver &resolver);
104-
105-
/// Determines how to access the registered file entry, letting you hook
106-
/// into how schemas are read to support other file formats, like YAML
107-
using Reader = std::function<JSON(const std::filesystem::path &)>;
108-
109-
/// Register a schema to the flat file resolver, returning the detected
110-
/// identifier for the schema
111-
auto add(
112-
const std::filesystem::path &path,
113-
const std::optional<std::string> &default_dialect = std::nullopt,
114-
const std::optional<std::string> &default_id = std::nullopt,
115-
const Reader &reader =
116-
[](const std::filesystem::path &path) { return read_json(path); },
117-
SchemaVisitorReference &&reference_visitor = nullptr)
118-
-> const std::string &;
119-
120-
// Change the identifier of a registered schema
121-
auto reidentify(const std::string &schema, const std::string &new_identifier)
122-
-> void;
123-
124-
/// Attempt to resolve a schema
125-
auto operator()(std::string_view identifier) const -> std::optional<JSON>;
126-
127-
/// Traverse the registered schemas using iterators
128-
inline auto begin() const -> auto { return this->schemas.begin(); }
129-
130-
/// Traverse the registered schemas using iterators
131-
inline auto end() const -> auto { return this->schemas.end(); }
132-
133-
/// Represent an entry in the resolver
134-
struct Entry {
135-
std::filesystem::path path;
136-
std::optional<std::string> default_dialect;
137-
std::string original_identifier;
138-
Reader reader;
139-
SchemaVisitorReference reference_visitor;
140-
};
141-
142-
private:
143-
// Exporting symbols that depends on the standard C++ library is considered
144-
// safe.
145-
// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
146-
#if defined(_MSC_VER)
147-
#pragma warning(disable : 4251)
148-
#endif
149-
std::map<std::string, Entry> schemas;
150-
SchemaResolver default_resolver = nullptr;
151-
#if defined(_MSC_VER)
152-
#pragma warning(default : 4251)
153-
#endif
154-
};
155-
15676
} // namespace sourcemeta::core
15777

15878
#endif

src/core/jsonschema/resolver.cc

Lines changed: 2 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#include <sourcemeta/core/jsonschema.h>
22

3-
#include <algorithm> // std::transform
4-
#include <cassert> // assert
5-
#include <cctype> // std::tolower
6-
#include <sstream> // std::ostringstream
3+
#include <cassert> // assert
4+
#include <sstream> // std::ostringstream
75

86
namespace sourcemeta::core {
97

@@ -84,98 +82,4 @@ auto SchemaMapResolver::operator()(std::string_view identifier) const
8482
return std::nullopt;
8583
}
8684

87-
SchemaFlatFileResolver::SchemaFlatFileResolver() {}
88-
89-
SchemaFlatFileResolver::SchemaFlatFileResolver(const SchemaResolver &resolver)
90-
: default_resolver{resolver} {}
91-
92-
static auto to_lowercase(const std::string_view input) -> std::string {
93-
std::string result{input};
94-
std::transform(result.cbegin(), result.cend(), result.begin(),
95-
[](const auto character) {
96-
return static_cast<char>(std::tolower(character));
97-
});
98-
return result;
99-
}
100-
101-
auto SchemaFlatFileResolver::add(
102-
const std::filesystem::path &path,
103-
const std::optional<std::string> &default_dialect,
104-
const std::optional<std::string> &default_id, const Reader &reader,
105-
SchemaVisitorReference &&reference_visitor) -> const std::string & {
106-
const auto canonical{std::filesystem::weakly_canonical(path)};
107-
const auto schema{reader(canonical)};
108-
assert(sourcemeta::core::is_schema(schema));
109-
const auto identifier{sourcemeta::core::identify(
110-
schema, *this, SchemaIdentificationStrategy::Loose, default_dialect,
111-
default_id)};
112-
if (!identifier.has_value() && !default_id.has_value()) {
113-
std::ostringstream error;
114-
error << "Cannot identify schema: " << canonical.string();
115-
throw SchemaError(error.str());
116-
}
117-
118-
// Filesystems behave differently with regards to casing. To unify
119-
// them, assume they are case-insensitive.
120-
const auto effective_identifier{to_lowercase(
121-
default_id.has_value() ? identifier.value_or(default_id.value())
122-
: identifier.value())};
123-
124-
const auto result{this->schemas.emplace(
125-
effective_identifier,
126-
Entry{canonical, default_dialect, effective_identifier, reader,
127-
reference_visitor ? std::move(reference_visitor)
128-
: reference_visitor_relativize})};
129-
if (!result.second && result.first->second.path != canonical) {
130-
std::ostringstream error;
131-
error << "Cannot register the same identifier twice: "
132-
<< effective_identifier;
133-
throw SchemaError(error.str());
134-
}
135-
136-
return result.first->first;
137-
}
138-
139-
auto SchemaFlatFileResolver::reidentify(const std::string &schema,
140-
const std::string &new_identifier)
141-
-> void {
142-
const auto result{this->schemas.find(to_lowercase(schema))};
143-
assert(result != this->schemas.cend());
144-
this->schemas.insert_or_assign(to_lowercase(new_identifier),
145-
std::move(result->second));
146-
this->schemas.erase(result);
147-
}
148-
149-
auto SchemaFlatFileResolver::operator()(std::string_view identifier) const
150-
-> std::optional<JSON> {
151-
const std::string string_identifier{to_lowercase(identifier)};
152-
const auto result{this->schemas.find(string_identifier)};
153-
if (result != this->schemas.cend()) {
154-
auto schema{result->second.reader(result->second.path)};
155-
assert(sourcemeta::core::is_schema(schema));
156-
if (schema.is_object() && !schema.defines("$schema") &&
157-
result->second.default_dialect.has_value()) {
158-
schema.assign("$schema", JSON{result->second.default_dialect.value()});
159-
}
160-
161-
sourcemeta::core::reidentify(schema, result->second.original_identifier,
162-
*this, result->second.default_dialect);
163-
// Because we allow re-identification, we can get into issues unless we
164-
// always try to relativize references
165-
sourcemeta::core::reference_visit(
166-
schema, schema_official_walker, *this, result->second.reference_visitor,
167-
result->second.default_dialect, result->second.original_identifier);
168-
sourcemeta::core::reidentify(schema, result->first, *this,
169-
result->second.default_dialect);
170-
171-
return schema;
172-
}
173-
174-
if (this->default_resolver) {
175-
return this->default_resolver(identifier);
176-
}
177-
178-
return std::nullopt;
179-
}
180-
18185
} // namespace sourcemeta::core

test/jsonschema/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ sourcemeta_googletest(NAMESPACE sourcemeta PROJECT core NAME jsonschema
8282
jsonschema_official_resolver_test.cc
8383
jsonschema_relativize_test.cc
8484
jsonschema_map_resolver_test.cc
85-
jsonschema_flat_file_resolver_test.cc
8685
jsonschema_format_test.cc
8786
jsonschema_wrap_test.cc)
8887

@@ -94,8 +93,6 @@ target_link_libraries(sourcemeta_core_jsonschema_unit
9493
PRIVATE sourcemeta::core::jsonschema)
9594
target_link_libraries(sourcemeta_core_jsonschema_unit
9695
PRIVATE sourcemeta::core::uri)
97-
target_compile_definitions(sourcemeta_core_jsonschema_unit
98-
PRIVATE SCHEMAS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/schemas")
9996

10097
# JSON Schema Referencing Suite
10198
# See https://github.com/python-jsonschema/referencing-suite

0 commit comments

Comments
 (0)