Coder Social home page Coder Social logo

Binding questions about json HOT 14 CLOSED

michael-brade avatar michael-brade commented on June 15, 2024
Binding questions

from json.

Comments (14)

michael-brade avatar michael-brade commented on June 15, 2024 1

Update: while reading, I found the is_nothing method, which is a good solution to the empty string problem. I would still like to understand TAO_JSON_BIND_OPTIONAL, however :)

from json.

ColinH avatar ColinH commented on June 15, 2024 1

And second, I have not been able to fully understand how TAO_JSON_BIND_OPTIONAL works. The enum member_kind is a boolean, so it seems that this is somehow/somewhere used in the json code but I did not find out.

Here's one detail. Both binding::object::to() and binding::object::consume() check whether all required keys were encountered when filling out the target object, either from a JSON value object (to()) or from Events (consume()).

Here you can see that the bitset used to track which member were already encountered initialises bits corresponding to optional members with true so that they will not be flagged as missing at the end of the aforementioned functions.

from json.

michael-brade avatar michael-brade commented on June 15, 2024 1

Here's one detail. Both binding::object::to() and binding::object::consume() check whether all required keys were encountered when filling out the target object, either from a JSON value object (to()) or from Events (consume()).

Here you can see that the bitset used to track which member were already encountered initialises bits corresponding to optional members with true so that they will not be flagged as missing at the end of the aforementioned functions.

Ohh, now I see! This little information is enough and suddenly everything is easily understood. Thanks 😁

from json.

michael-brade avatar michael-brade commented on June 15, 2024 1

One question that I still have is: if I derive from binding::object<> and implement static void assign(), the latter is not called anymore. Is it possible to somehow change the code so that assign is called even when using the binding traits?

I'm no quite following. You implemented assign() for some traits specialisation that is derived from binding::object<...> which brings its own assign(). Why the extra assign() in the derived class? Why do you still need the one from the base class if there were reasons to roll your own?

Yes. Well, originally I didn't have a solution for all the traits' types using just TAO_JSON_BIND_REQUIRED . Now I have found solutions for pretty much every problem and don't really need this - for the time being. But I am not finished yet with all my classes, so if it turns out I need some manual processing for a member, this may be the simplest solution.

And, just to be sure, calling the base class' assign() from your own in the derived class is not the solution?

no, since the assign() in my own class will not be called anymore... so trying to call the base from it doesn't change anything.

from json.

ColinH avatar ColinH commented on June 15, 2024

One problem is that the id() getter is static, that won't work. Binding does work with getters, but if they are a part of the struct/class then they can't be static and need to be declared const. (A static getter doesn't make much sense, or at least I haven't yet seen a use case where it does.)

from json.

ColinH avatar ColinH commented on June 15, 2024

Is the "container" you are referring to the std::string_view returned by magic_enum::enum_name()?

from json.

ColinH avatar ColinH commented on June 15, 2024

For your second question, could you please sketch out an example of what you are trying to do? What exactly do you want to convert?

from json.

michael-brade avatar michael-brade commented on June 15, 2024

Thank you! Regarding static: sounds good, I used static in this example because I didn't know the syntax for a non-static getter, and the test was supposed to focus on the TAO_JSON_BIND_REQUIRED problem. And yes, the container is the std::string_view container.

An example would be a method that returns a std::chrono::sys_days and I want to format the date. Like this:

namespace tools {
   using date_t = std::chrono::sys_days;

   static std::string toFormattedString(date_t value) {
       ...
   }
}

struct test {
    enum class Keys {
        date // each getter is available in the enum Keys
    }

    tools::date_t date() const noexcept {
        return m_date;
    }
 
    int id;
    tools::date_t m_date;
};


// with this, I would like a traits class that translates the `test` struct to json:

template<typename T, typename = void>
struct my_traits
    : public tao::json::traits<T>
{};

template<>
struct my_traits<test>
    : public tao::json::binding::object<TAO_JSON_BIND_REQUIRED(magic_enum::enum_name(test::Keys::date), &test::date)>
{};

Obviously, &test::date won't work, and it won't call tools::toFormattedString() either. I have no idea yet how to do either of them yet 😇

So in the meantime, I dropped the magic_enum, using the name of the member directly, and only added member variables to ...binding::object<>. Then I tried to implement assign() in my_traits:

template<>
struct my_traits<test>
    : public tao::json::binding::object<TAO_JSON_BIND_REQUIRED("id", &test::id)>
{
	template<template<typename...> class Traits>
	static void assign(tao::json::basic_value<Traits>& v, const test& t)
	{
		// v is uninitialized here...
		v = {
			{ "date", tools::toFormattedString(t.date()) }
		};
	}
};

Next problem: when implementing assign, the binding super-class has no effect anymore, only the date value is in the final json...

from json.

ColinH avatar ColinH commented on June 15, 2024

Regarding the string views, it should be possible to rework everything so that the right thing happens when you directly use a string view as first argument to TAO_JSON_BIND_REQUIRED, but it'll probably take a bit of time to get everything sorted out and I'll have to look into this in more detail.

from json.

ColinH avatar ColinH commented on June 15, 2024

There are three possibilities for the second argument to TAO_JSON_BIND_REQUIRED, you can bind directly to a member variable of the class in question, you can bind to a non-static const member function of the class that returns a value, and you can bind to a global function that takes a const reference to a class instance as single argument.

So you can't directly use toFormattedString(), but what does currently work is a small wrapper function that combines extraction of the correct member and the conversion like std::string get_test_date( const test& t ) { return toFormattedString( t.date() ); }.

Note that if you bypass TAO_JSON_BIND_REQUIRED and directly use tao::json::binding::member2, instead of tao::json::binding::member as used by the macro, you can supply two functions, a getter and a setter, to enable both the object-to-JSON and JSON-to-object directions.

from json.

michael-brade avatar michael-brade commented on June 15, 2024

Regarding the string views, it should be possible to rework everything so that the right thing happens when you directly use a string view as first argument to TAO_JSON_BIND_REQUIRED, but it'll probably take a bit of time to get everything sorted out and I'll have to look into this in more detail.

perfect! That would be great :) But it doesn't have the highest priority since I can use this solution only when the other challenges are solved.

One question that I still have is: if I derive from binding::object<> and implement static void assign(), the latter is not called anymore. Is it possible to somehow change the code so that assign is called even when using the binding traits?

And second, I have not been able to fully understand how TAO_JSON_BIND_OPTIONAL works. The enum member_kind is a boolean, so it seems that this is somehow/somewhere used in the json code but I did not find out. The reason I am asking is: I would like to override the traits< std::string > to treat the empty string ("") as if it were an empty std::optional. How can I do that?

from json.

ColinH avatar ColinH commented on June 15, 2024

One question that I still have is: if I derive from binding::object<> and implement static void assign(), the latter is not called anymore. Is it possible to somehow change the code so that assign is called even when using the binding traits?

I'm no quite following. You implemented assign() for some traits specialisation that is derived from binding::object<...> which brings its own assign(). Why the extra assign() in the derived class? Why do you still need the one from the base class if there were reasons to roll your own? And, just to be sure, calling the base class' assign() from your own in the derived class is not the solution?

from json.

michael-brade avatar michael-brade commented on June 15, 2024

oh, are you sure this is completed? ;-)

  • I would still like to use a string view as first argument to TAO_JSON_BIND_REQUIRED - should this be a new issue?
  • I cannot overwrite assign() in binding traits

from json.

ColinH avatar ColinH commented on June 15, 2024

I was hoping your workarounds sere sufficient ;-)

Yes, please open a new issue for every individual topic to keep things cleanly separated.

from json.

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.