|
|
@@ -0,0 +1,93 @@
|
|
|
+#include <cstdio>
|
|
|
+#include <cstdlib>
|
|
|
+#include <filesystem>
|
|
|
+#include <fstream>
|
|
|
+#include <iostream>
|
|
|
+#include <stdexcept>
|
|
|
+
|
|
|
+#include <curl/curl.h>
|
|
|
+
|
|
|
+#include <jvalidate/adapter.h>
|
|
|
+#include <jvalidate/adapters/jsoncpp.h>
|
|
|
+#include <jvalidate/enum.h>
|
|
|
+#include <jvalidate/schema.h>
|
|
|
+#include <jvalidate/status.h>
|
|
|
+#include <jvalidate/uri.h>
|
|
|
+#include <jvalidate/validator.h>
|
|
|
+
|
|
|
+#include <json/reader.h>
|
|
|
+#include <json/value.h>
|
|
|
+#include <json/writer.h>
|
|
|
+
|
|
|
+bool load_stream(std::istream & in, Json::Value & out) {
|
|
|
+ Json::CharReaderBuilder builder;
|
|
|
+ std::string error;
|
|
|
+ return Json::parseFromStream(builder, in, &out, &error);
|
|
|
+}
|
|
|
+
|
|
|
+bool load_file(std::filesystem::path const & path, Json::Value & out) {
|
|
|
+ std::ifstream in(path);
|
|
|
+ return load_stream(in, out);
|
|
|
+}
|
|
|
+
|
|
|
+size_t transfer_to_buffer(char * data, size_t size, size_t nmemb, void * userdata) {
|
|
|
+ std::stringstream & ss = *reinterpret_cast<std::stringstream *>(userdata);
|
|
|
+ size_t actual_size = size * nmemb;
|
|
|
+ ss << std::string_view(data, actual_size);
|
|
|
+ return actual_size;
|
|
|
+}
|
|
|
+
|
|
|
+Json::Value load_stream(std::filesystem::path const & file) {
|
|
|
+ std::ifstream in(file);
|
|
|
+ Json::Value json;
|
|
|
+ Json::CharReaderBuilder builder;
|
|
|
+ std::string error;
|
|
|
+ if (!Json::parseFromStream(builder, in, &json, &error)) {
|
|
|
+ throw std::invalid_argument(error);
|
|
|
+ }
|
|
|
+ return json;
|
|
|
+}
|
|
|
+
|
|
|
+bool curl_get(jvalidate::URI const & uri, Json::Value & out) {
|
|
|
+ if (uri.scheme().starts_with("http")) {
|
|
|
+ std::stringstream ss;
|
|
|
+ if (CURL * curl = curl_easy_init(); curl) {
|
|
|
+ curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ss);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &transfer_to_buffer);
|
|
|
+
|
|
|
+ CURLcode res = curl_easy_perform(curl);
|
|
|
+ curl_easy_cleanup(curl);
|
|
|
+
|
|
|
+ if (res == CURLE_OK) {
|
|
|
+ return load_stream(ss, out);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ } else if (uri.scheme() == "file") {
|
|
|
+ return load_file(uri.resource(), out);
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int main(int argc, char const * const * argv) {
|
|
|
+ if (argc <= 2) {
|
|
|
+ std::cerr << "usage: " << argv[0] << " schema object\n";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ Json::Value jschema = load_stream(argv[1]);
|
|
|
+ Json::Value jobject = load_stream(argv[2]);
|
|
|
+
|
|
|
+ using enum jvalidate::schema::Version;
|
|
|
+ jvalidate::Schema schema(jschema, Draft2020_12, &curl_get);
|
|
|
+
|
|
|
+ jvalidate::ValidationResult result;
|
|
|
+ if (!jvalidate::Validator(schema).validate(jobject, &result)) {
|
|
|
+ std::cout << result;
|
|
|
+ }
|
|
|
+
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|