Coder Social home page Coder Social logo

Comments (10)

beached avatar beached commented on June 11, 2024

Do you have any example JSON for this? It seems like the shared_ptr in this case could only be an int/bool and because the mapping is an alias there is no class alternative at this point. I am not fully understanding

from daw_json_link.

andreasdamm-shure avatar andreasdamm-shure commented on June 11, 2024

Probably not quite right using json_class_null_no_name, json_link_no_name might be the correct json link type.

Example JSON would be

[
  true,
  false,
  42,
  [
    1,
    2,
    3,
    [
      true,
      [
        1,
        false
      ]
    ]
  ]
]

The JSON schema I am trying to implement is as follows

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "value": {
      "oneOf": [
        {
          "type": "number"
        },
        {
          "type": "boolean"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/definitions/value"
          }
        }
      ]
    }
  },
  "allOf": [
    {
      "$ref": "#/definitions/value"
    }
  ]
}

from daw_json_link.

beached avatar beached commented on June 11, 2024

I think this needs to go into the raw mapping type. So something like https://jsonlink.godbolt.org/z/nnoT8ssqY

#include <daw/json/daw_json_link.h>

#include <cassert>
#include <string>
#include <utility>
#include <variant>
#include <vector>

struct Variant {
    std::variant<int, bool, std::vector<Variant>> value;
};

struct VariantCtor {
    Variant operator()(char const *ptr, std::size_t sz) const {
        auto value = daw::json::json_value(std::string_view(ptr, sz));
        return operator()(value);
    }

    Variant operator()(daw::json::json_value value) const {
        using namespace daw::json;
        switch (value.type()) {
            case JsonBaseParseTypes::Number:
                return Variant{from_json<int>(value)};
            case JsonBaseParseTypes::Bool:
                return Variant{from_json<bool>(value)};
            case JsonBaseParseTypes::Array: {
                auto res = std::vector<Variant>();
                for (auto jp : value) {
                    res.push_back(operator()(jp.value));
                }
                return Variant{std::move(res)};
            }
            default:
                std::abort();
        }
    }
};

namespace daw::json {
template <>
struct json_data_contract<Variant> {
    using type = json_type_alias<json_raw_no_name<
        std::variant<int, bool, std::vector<Variant>>, VariantCtor>>;

    static auto to_json_data(const Variant &value) { return value.value; }
};
}  // namespace daw::json

int main() {
    {
        constexpr std::string_view json_doc = "5";
        auto i = daw::json::from_json<Variant>(json_doc);
        assert(i.value.index() == 0);
    }
    {
        constexpr std::string_view json_doc = "false";
        auto b0 = daw::json::from_json<Variant>(json_doc);
        assert(b0.value.index() == 1);
    }
    {
        constexpr std::string_view json_doc = "true";
        auto b1 = daw::json::from_json<Variant>(json_doc);
        assert(b1.value.index() == 1);
    }
    {
        constexpr std::string_view json_doc =
            "[1, true, false, [1, false, []]]";
        auto ary = daw::json::from_json<Variant>(json_doc);
        assert(ary.value.index() == 2);
    }
}

from daw_json_link.

beached avatar beached commented on June 11, 2024

Serialization of that currently needs more manual than I would like though.

from daw_json_link.

andreasdamm-shure avatar andreasdamm-shure commented on June 11, 2024

Does the constructor and json_value approach cover serialization?

from daw_json_link.

beached avatar beached commented on June 11, 2024

Unfortunately, I don't see an easy path here. recursive DS's isn't something that has been considered and should get better support in the future.

from daw_json_link.

beached avatar beached commented on June 11, 2024

This will have to be a separate thing for recursive DS's as it's unbounded at compile time. The depth/length isn't known until the data is parsed.

from daw_json_link.

andreasdamm-shure avatar andreasdamm-shure commented on June 11, 2024

I have been exploring the use of json_custom_no_name with an option of options::json_custom_opt(options::JsonCustomTypes::Literal which allows for serialization. Deserialization doesn't work that way as only primitive types are allowed. Using options::JsonCustomTypes::Any may be a way forward but serialzation puts double quotes around output.

Thinking about using the alternative mappings feature to use json_value for parsing and json_custom for serialization.

from daw_json_link.

andreasdamm-shure avatar andreasdamm-shure commented on June 11, 2024

An advantage of using the conversion class in the json_custom approach is that when splitting conversion operator into declaration before data contracts are declared and definition into after they have been declared is that the definition can now use the established contract to call to_json on data like itself.

Maybe that might be an approach for recursive structures in general -- somehow using the definition/declaration split around the contract to be able to refer back to itself.

from daw_json_link.

beached avatar beached commented on June 11, 2024

I think a generalized recursive approach will need an explicit stack for when the depth gets deep there isn't a stack overflow. There have been attacks that hit JSON libraries like this in the past. That hasn't been needed so far as everything is bounded by the type systems limits.

from daw_json_link.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.