Files
json/main.cpp

200 lines
5.5 KiB
C++

#include <json.hpp>
#include <iostream>
#include <fstream>
/// Open a text file and return the contents.
std::string read_file(const std::string& file_path)
{
std::ifstream file(file_path, std::ios::binary);
if (!file)
throw std::runtime_error("We couldn't find the file: " + file_path);
std::streamsize file_size;
file.seekg(0, std::ios::end);
file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::string file_content(file_size, '\0');
file.read(&file_content[0], file_size);
file.close();
return file_content;
}
void parse_json_file(const std::string& file_path) {
auto file_content = read_file(file_path);
auto [text, parse_error] = json::parse(file_content);
if (!parse_error.empty())
std::cerr << "Error while parsing json: " << parse_error << std::endl;
std::cout << json::deparse(text) << std::endl;
}
struct Vector3
{
float x, y, z;
};
/// Creates json array out of Vector3 type.
json::value vector3_to_json(const Vector3& v) {
//auto x = json::number(input.x);
//auto y = json::number(input.y);
//auto z = json::number(input.z);
return json::array({json::number(v.x), json::number(v.y), json::number(v.z)});
}
/// Creates Vector3 type out of json array object.
Vector3 json_to_vector3(const json::value& val) {
Vector3 value;
auto arr = val.as_array_value();
value.x = arr[0].as_float_or(0);
value.y = arr.at(1).as_float_or(0);
value.z = arr.at(2).as_float_or(0);
return {value};
}
struct product_info
{
[[nodiscard]] json::value serialize() const;
product_info() = default;
/// @schema object {string category, string description, boolean is_available, string name, number price, array[@review] reviews}
/// @note This class design assumes all entries in `reviews` are serializable to @struct review,
///
explicit product_info(const json::value& jv);
struct rating_metrics {
double average;
int total;
};
/// @schema { rating : number, review_text : string, user : string }
struct review {
[[nodiscard]] json::value serialize() const;
explicit review(const json::value& jv);
int rating;
std::string review_text;
std::string user;
};
std::string category;
std::string description;
bool is_available;
std::string manufacturer;
std::string name;
double price;
std::string product_id;
rating_metrics ratings;
std::string release_date;
std::vector<review> reviews;
};
json::value product_info::serialize() const {
json::object root;
root.insert("category", this->category);
root += {"category", json::string( this->category)};
root += {"manufacturer", json::string( this->manufacturer)};
root += {"is_available", json::boolean(this->is_available)};
root += {"description", json::string( this->description)};
root += {"name", json::string( this->name)};
auto review_list = json::array();
for (auto& rev : this->reviews)
review_list += rev.serialize();
root["ratings"] = json::object({
{"average", json::number(this->ratings.average)},
{"total", json::number(this->ratings.total)}
});
root += {"reviews", review_list};
root += {"taters", json::number(5)};
return root;
}
product_info::product_info(const json::value &jv) {
if (jv.type != json::value_type::object)
throw std::runtime_error("Malformed JSON for product info!");
auto jvo = jv.as_object();
this->category = jvo["category"].as_string();
this->description = jvo["description"].as_string();
this->is_available = jvo["is_available"].as_bool();
this->manufacturer = jvo["manufacturer"].as_string();
this->name = jvo["name"].string.value();
this->price = double(jvo["price"]);
for (auto& review_json : jvo["reviews"].as_array()) {
this->reviews.emplace_back(review_json);
}
this->ratings.average = jvo["ratings"]["average"].number.value();
this->ratings.total = jvo["ratings"]["total"].number.value();
}
json::value product_info::review::serialize() const {
json::object obj = json::object();
obj["rating"] = json::number(rating);
obj["review_text"] = json::string(review_text);
obj["user"] = json::string(user);
return obj;
}
product_info::review::review(const json::value &jv) {
if (jv.type != json::value_type::object)
throw std::runtime_error("Malformed JSON for review!");
rating = jv["rating"].as_int();
review_text = jv["review_text"].as_string();
user = jv["user"].as_string();
}
void test_product_info()
{
std::cout << "Testing parsing of product_info file." << std::endl;
//parse_json_file("../samples/product_info.json");
auto file_contents = read_file("../samples/product_info.json");
auto [text, err] = json::parse(file_contents);
if (!err.empty()) {
std::cerr << err << std::endl;
return;
}
std::cout << "Testing deserialization of product_info json." << std::endl;
// Construct from json object.
product_info test(text);
std::cout << "Testing serialization of product_info struct." << std::endl;
json::value result = test.serialize();
result.convert_descendants();
std::cout << json::deparse(result);
}
void test_tile_data() {
//parse_json_file("../samples/tiles.json");
}
void test_widgets() {
}
// Some progress has been made on small scale.
int main(int argc, char* argv[]) {
test_product_info();
test_tile_data();
}