glaze icon indicating copy to clipboard operation
glaze copied to clipboard

can't skip null on custom lambda

Open JimjunZhang opened this issue 1 year ago • 2 comments

Hello, I am using custom Lambda to output a field or skip based on a condition, but I found it can't skip the null.

sample code:

struct my_struct
{
    int i = 287;
    double d = 3.14;
   
};
template <>
struct glz::meta<my_struct> {
    using T = my_struct;
    static constexpr auto read_test = [](T& s, const std::string& input) {};
    static constexpr auto write_test =
        [](auto& s) ->std::unique_ptr<std::string> {
        if (287 != s.i)
            return std::make_unique<std::string>("expected: not 278");
        else
            return std::unique_ptr<std::string>();
        };
    static constexpr auto value = object(
        "i", & T::i,
        "d", & T::d,
        "test", glz::custom<read_test, write_test>
    );
};

Use it:

my_struct obj;
std::string buffer;
auto ec = glz::write < glz::opts{ .prettify = true } > (obj, buffer);

The output is: { "i": 287, "d": 3.14, "test": null } But I would expect the null can be skipped. Is it to add this feature for custom lambda? thanks!

JimjunZhang avatar Oct 26 '24 01:10 JimjunZhang

Thanks for reporting this issue. Will look into it soon.

stephenberry avatar Oct 27 '24 16:10 stephenberry

So, this will require a significant amount of compile time programming, because we need to deduce the type of the return of the custom function. If the type is nullable then we need to decode the value within the object reading code and determine if the value is null so that we can skip writing out keys.

Because this fix would affect object serialization code, I'm going to spend some time considering this issue and tackle it when I have a good amount of time to determine a flexible solution. So, I would expect it to be a while until this feature is added. But, thanks for bringing this up!

stephenberry avatar Oct 28 '24 13:10 stephenberry

I gave this another attempt. It's extremely complicated. Will try again after more code cleanup.

stephenberry avatar May 02 '25 16:05 stephenberry

This issue was inadvertently fixed in commit 20e53e56 on December 13, 2024 ("Mustache improvements and moving get_member out of detail namespace").

The key change was in glaze/core/reflect.hpp:130:

template <size_t I>
using type = member_t<V, decltype(get<I>(values))>;

By using member_t, the field_t<T, I> type alias now correctly resolves to the lambda's return type rather than the lambda type itself. This allows the existing null_t concept checking to work correctly for lambda return values.

Verification tests have been added in: https://github.com/stephenberry/glaze/pull/2059

stephenberry avatar Nov 11 '25 19:11 stephenberry