diff --git a/include/JJX/JJX.hpp b/include/JJX/JJX.hpp index 8034385..f128cb2 100644 --- a/include/JJX/JJX.hpp +++ b/include/JJX/JJX.hpp @@ -6,52 +6,4 @@ #include #include -namespace JJX -{ - namespace json { - enum class token_type { string, number, syntax, boolean, null }; - enum class value_type { string, number, object, array, boolean, null}; - struct token { - std::string value; - token_type type; - int location; - std::shared_ptr full_source; - }; - - struct value { - std::optional string; - std::optional number; - std::optional boolean; - std::optional> array; - std::optional> object; - value_type type; - }; - - struct string_val: value { std::string data; }; - - struct number_val : value { double data; }; - - struct boolean_val : value { bool data; }; - - struct object_val : value { std::map data; }; - - struct array_val : value { std::vector data; }; - - std::tuple, std::string> lex(std::string); - std::tuple parse(std::vector, int index = 0); - std::tuple parse(std::string); - std::string deparse(json::value, std::string whitespace = ""); - - value string(const std::string& text); - - value number(double input); - - value boolean(bool input); - - value array(std::vector input); - - template - value array_of(const std::vector& input); - } - namespace xml {} -} \ No newline at end of file +#include \ No newline at end of file diff --git a/include/JJX/JSON.hpp b/include/JJX/JSON.hpp new file mode 100644 index 0000000..a304e45 --- /dev/null +++ b/include/JJX/JSON.hpp @@ -0,0 +1,81 @@ +#pragma once + +namespace JJX::json { + enum class token_type { string, number, syntax, boolean, null }; + enum class value_type { string, number, object, array, boolean, null}; + struct token { + std::string value; + token_type type; + int location; + std::shared_ptr full_source; + }; + + struct value + { + std::optional string; + std::optional number; + std::optional boolean; + std::optional> array; + std::optional> object; + value_type type; + + + void operator=(double in); + void operator=(const std::string& in); + void operator=(bool in); + void operator=(std::vector in); + void operator=(std::map in); + + explicit operator double() const { return number.value(); } + operator std::string() const { return string.value(); } + explicit operator bool() const { return boolean.value(); } + explicit operator std::vector() const { return array.value(); } + explicit operator std::map() const { return object.value(); } + }; + + struct string_val : value + { + void operator=(const std::string& me) + { + string = me; + } + operator std::string() + { + return string.value(); + } + }; + struct number_val : value {}; + struct boolean_val : value {}; + struct object_val : value + { + void add(const std::string& key, value val); + void add(const std::string& key, const std::string& val); + value& operator[] (const std::string& key); + + }; + struct array_val : value + { + void add(value val); + value& operator[] (int key); + }; + + std::tuple, std::string> lex(std::string); + std::tuple parse(std::vector, int index = 0); + std::tuple parse(std::string); + std::string deparse(json::value, std::string whitespace = ""); + + string_val string(const std::string& text); + + value number(double input); + + value boolean(bool input); + + array_val array(std::vector input); + array_val array(); + + object_val object(std::map input); + object_val object(); + + template + value array_of(const std::vector& input); +} diff --git a/main.cpp b/main.cpp index 2fecf35..a4fba79 100644 --- a/main.cpp +++ b/main.cpp @@ -61,9 +61,104 @@ Vector3 json_to_vector3(const json::value& obj) return value; } -int main(int argc, char* argv[]) { - parse_json_file("../samples/product_info.json"); + +struct product_info +{ + struct rating_metrics { + double average; + int total; + }; + + struct review + { + int rating; + std::string review_text; + std::string user; + + operator json::object_val() const + { + json::object_val obj = json::object(); + obj["rating"] = json::number(rating); + obj["review_text"] = json::string(review_text); + obj["user"] = json::string(user); + return obj; + } + }; + + 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 reviews; +}; - std::cout << json::deparse(vector3_to_json({2,4.5f, 31})); +product_info pinfo_fromjson(json::value root) +{ + if (root.type != json::value_type::object) + std::cerr << "Malformed product info file!" << std::endl; + + product_info this_product; + + json::object_val better_root = static_cast(root); + + this_product.category = better_root["category"]; + this_product.description = better_root["description"]; + this_product.is_available = bool(better_root["is_available"]); + this_product.manufacturer = better_root["manufacturer"]; + this_product.name = better_root["name"]; + this_product.price = double(better_root["price"]); + + + json::object_val subobj = static_cast(better_root["reviews"]); + + for (auto& review_data : subobj) + { + product_info::review going_in; + going_in.rating = review_data.object.value().at("rating").number.value(); + going_in.user = review_data.object.value().at("user").string.value(); + going_in.review_text = review_data.object.value().at("review_text").string.value(); + this_product.reviews.push_back(going_in); + } + + return this_product; +} + +json::value pinfo_tojson(product_info input) +{ + json::object_val root = json::object(); + root["category"] = json::string(input.category); + root["manufacturer"] = json::string(input.manufacturer); + root["is_available"] = input.is_available; + //root.add("category", input.category); + root.add("description", input.description); + root["name"] = input.name; + root["reviews"] = json::array(); + for (auto& rev : input.reviews) { + root["reviews"].array.value().push_back(rev); + } + + root["taters"] = 5.0; + + return root; +} + + +int main(int argc, char* argv[]) { + //parse_json_file("../samples/product_info.json"); + auto file_contents = read_file("../samples/product_info.json"); + + auto [text, err] = json::parse(file_contents); + + product_info test = pinfo_fromjson(text); + + + auto result = pinfo_tojson(test); + + std::cout << json::deparse(result); } diff --git a/src/JSON.cpp b/src/JSON.cpp index 831054b..c2c455c 100644 --- a/src/JSON.cpp +++ b/src/JSON.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace JJX::json { @@ -172,6 +173,61 @@ namespace JJX::json { return lex_keyword(raw_json, "false", token_type::boolean, index); } + void value::operator=(double in) + { + type = value_type::number; + number = in; + } + + void value::operator=(const std::string& in) + { + type = value_type::string; + string = in; + } + + void value::operator=(bool in) + { + type = value_type::boolean; + boolean = in; + } + + void value::operator=(std::vector in) + { + type = value_type::array; + array = in; + } + + void value::operator=(std::map in) + { + type = value_type::object; + object = in; + } + + void object_val::add(const std::string& key, value val) + { + object.value().emplace(key, val); + } + + void object_val::add(const std::string& key, const std::string& val) + { + object.value().emplace(key, json::string(val)); + } + + value& object_val::operator[](const std::string& key) + { + return object.value()[key]; + } + + void array_val::add(value val) + { + array.value().push_back(val); + } + + value& array_val::operator[](int key) + { + return array.value()[key]; + } + std::tuple, std::string> lex(std::string raw_json) { std::vector tokens; // All tokens will embed a pointer to the raw JSON for debugging purposes @@ -400,11 +456,12 @@ namespace JJX::json { } } - value string(const std::string &text) { - return { - .string = text, - .type = value_type::string - }; + string_val string(const std::string &text) { + string_val out; + out.type = value_type::string; + out.string = text; + + return out; } value number(double input) { @@ -421,9 +478,9 @@ namespace JJX::json { }; } - value array(std::vector input) + array_val array(std::vector input) { - value arr; + array_val arr; arr.type = value_type::array; arr.array = std::vector(); @@ -434,4 +491,28 @@ namespace JJX::json { return arr; } + + array_val array() + { + array_val out; + out.type = value_type::array; + out.array = std::vector(); + return out; + } + + object_val object(std::map input) + { + object_val out; + out.type = value_type::object; + out.object = input; + return out; + } + + object_val object() + { + object_val out; + out.type = value_type::object; + out.object = std::map(); + return out; + } }