Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate JSON entry for empty std::optional #666

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

lowsfer
Copy link

@lowsfer lowsfer commented Dec 19, 2020

This change remove the entry in JSON if what is being serialized/deserialized is of type std::optional, and the value is std::nullopt. When it's not std::nullopt, only the contained value (T) is saved, instead of a flag plus the value.

This is helpful when using JSON as web protocol. People would want to eliminate optional entries when they are empty. This improved human-readability of the JSON protocol and make it easier to interact with other languages.

@lowsfer
Copy link
Author

lowsfer commented Dec 19, 2020

Seems this is exactly what is requested here:
#459

@WSoptics
Copy link
Contributor

It might be a good idea to make this an option of JSONArchive instead of altering its default behavior?

@lowsfer
Copy link
Author

lowsfer commented Aug 15, 2021

@WSoptics Changed it to an option and defaults to false. Also added unit tests.

@fiesh
Copy link
Contributor

fiesh commented Aug 16, 2021

I like the change but can't merge :-)

One thing though however, it seems the option is only available for C++17, which seems not really necessary?

You should probably ping @AzothAmmo to potentially have it merged.

@lowsfer
Copy link
Author

lowsfer commented Aug 22, 2021

@fiesh std::optional is only available since C++17. You mean keep the option but leave it with no effect?

@AzothAmmo Can we merge this feature?

@fiesh
Copy link
Contributor

fiesh commented Aug 23, 2021

@fiesh std::optional is only available since C++17. You mean keep the option but leave it with no effect?

Sorry, I somehow thought std::optional was C++11 -- you're right of course!

@winding-lines
Copy link

Would also love to have this behavior in cereal, @AzothAmmo :)

@lowsfer
Copy link
Author

lowsfer commented Sep 15, 2022

It has been ~1.75 years.
@AzothAmmo Do you have any concerns on this PR?

@akalsi87
Copy link

This seems like a good change, and one that makes the output more intuitive and interoperable. Any reason for the delay in merging this in?

@yuziqii
Copy link

yuziqii commented Oct 20, 2023

@lowsfer it seems this change can't support out-of-order json fileds.

@yuziqii
Copy link

yuziqii commented Oct 27, 2023

I made a few changes to support out-of-order JSON fields. It works fine in my case, but I don't know if there are any side effects.

here are my changes:

template <class T> inline  std::enable_if_t<IsOptional<T>::value>
CEREAL_LOAD_FUNCTION_NAME( JSONInputArchive & ar, NameValuePair<T> & t )
{
  if (ar.skippedNullopt())
  {
    // search node name
    if (ar.searchNodeName(t.name))
    {
      ar.setNextName( t.name );
      std::decay_t<decltype(*t.value)> val;
      ar( val );
      t.value = std::move(val);
    }
    else
    {
      t.value = std::nullopt;
    }
  }
  else
  {
    loadImpl(ar, t);
  }
}
const char* searchNodeName(const char* name) const
{
  auto currentIterator = itsIteratorStack.back();
  const auto len = std::strlen( name );
  for (const auto& it : currentIterator)
  {
    const auto currentName = it.name.GetString();
    if( ( std::strncmp( name, currentName, len ) == 0 ) &&
        ( std::strlen( currentName ) == len ) )
    {
    return currentName;
    }
  }
  return nullptr;
}
// Iterator support range for syntax
auto begin()
{
  return itsMemberItBegin;
}

auto end()
{
   return itsMemberItEnd;
}

@lowsfer
Copy link
Author

lowsfer commented Mar 31, 2024

@yuziqii Would you like to create a commit including your changes? You can create an PR into my forked branch lowsfer:eliminate-empty-optional, then I merge it and your commit will be included in this PR.

@yuziqii
Copy link

yuziqii commented Apr 1, 2024

@lowsfer Sure, I'd be happy to submit a PR , and I've already done that. Let me know if there's any problems. here is the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants