validate.cxx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <filesystem>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <stdexcept>
  7. #include <curl/curl.h>
  8. #include <jvalidate/adapter.h>
  9. #include <jvalidate/adapters/jsoncpp.h>
  10. #include <jvalidate/enum.h>
  11. #include <jvalidate/schema.h>
  12. #include <jvalidate/status.h>
  13. #include <jvalidate/uri.h>
  14. #include <jvalidate/validator.h>
  15. #include <json/reader.h>
  16. #include <json/value.h>
  17. #include <json/writer.h>
  18. bool load_stream(std::istream & in, Json::Value & out) {
  19. Json::CharReaderBuilder builder;
  20. std::string error;
  21. return Json::parseFromStream(builder, in, &out, &error);
  22. }
  23. bool load_file(std::filesystem::path const & path, Json::Value & out) {
  24. std::ifstream in(path);
  25. return load_stream(in, out);
  26. }
  27. size_t transfer_to_buffer(char * data, size_t size, size_t nmemb, void * userdata) {
  28. std::stringstream & ss = *reinterpret_cast<std::stringstream *>(userdata);
  29. size_t actual_size = size * nmemb;
  30. ss << std::string_view(data, actual_size);
  31. return actual_size;
  32. }
  33. Json::Value load_stream(std::filesystem::path const & file) {
  34. std::ifstream in(file);
  35. Json::Value json;
  36. Json::CharReaderBuilder builder;
  37. std::string error;
  38. if (!Json::parseFromStream(builder, in, &json, &error)) {
  39. throw std::invalid_argument(error);
  40. }
  41. return json;
  42. }
  43. bool curl_get(jvalidate::URI const & uri, Json::Value & out) {
  44. if (uri.scheme().starts_with("http")) {
  45. std::stringstream ss;
  46. if (CURL * curl = curl_easy_init(); curl) {
  47. curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
  48. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  49. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ss);
  50. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &transfer_to_buffer);
  51. CURLcode res = curl_easy_perform(curl);
  52. curl_easy_cleanup(curl);
  53. if (res == CURLE_OK) {
  54. return load_stream(ss, out);
  55. }
  56. }
  57. return false;
  58. } else if (uri.scheme() == "file") {
  59. return load_file(uri.resource(), out);
  60. } else {
  61. return false;
  62. }
  63. }
  64. int main(int argc, char const * const * argv) {
  65. if (argc <= 2) {
  66. std::cerr << "usage: " << argv[0] << " schema object\n";
  67. return EXIT_FAILURE;
  68. }
  69. Json::Value jschema = load_stream(argv[1]);
  70. Json::Value jobject = load_stream(argv[2]);
  71. using enum jvalidate::schema::Version;
  72. jvalidate::Schema schema(jschema, Draft2020_12, &curl_get);
  73. jvalidate::ValidationResult result;
  74. if (!jvalidate::Validator(schema).validate(jobject, &result)) {
  75. std::cout << result;
  76. }
  77. return EXIT_SUCCESS;
  78. }