Added support for specifying floating value's format on serializing DTO to JSON

The program does not check the format, you need to make sure it is right.

demo:
class MyDto : public DTO {

  DTO_INIT(MyDto, DTO)

  DTO_FIELD_INFO(value) {
    info->format = "%.2f";
  }
  DTO_FIELD(Float64, value);

};
This commit is contained in:
doufu3344 2022-10-11 14:07:43 +08:00
parent bbe455af60
commit f78c4c026f
9 changed files with 191 additions and 2 deletions

View File

@ -102,6 +102,10 @@ public:
*/
std::string pattern = "";
/**
* Format.
*/
std::string format = OATPP_FLOAT_STRING_FORMAT;
/**
* Required.
*/

View File

@ -399,7 +399,7 @@ v_io_size ConsistentOutputStream::writeAsString(v_uint64 value){
v_io_size ConsistentOutputStream::writeAsString(v_float32 value){
v_char8 a[100];
auto size = utils::conversion::float32ToCharSequence(value, &a[0], 100);
auto size = utils::conversion::float32ToCharSequence(value, &a[0], 100, floatFormat->c_str());
if(size > 0){
return writeSimple(&a[0], size);
}
@ -408,7 +408,7 @@ v_io_size ConsistentOutputStream::writeAsString(v_float32 value){
v_io_size ConsistentOutputStream::writeAsString(v_float64 value){
v_char8 a[100];
auto size = utils::conversion::float64ToCharSequence(value, &a[0], 100);
auto size = utils::conversion::float64ToCharSequence(value, &a[0], 100, floatFormat->c_str());
if(size > 0){
return writeSimple(&a[0], size);
}

View File

@ -405,6 +405,7 @@ public:
*/
class ConsistentOutputStream : public OutputStream {
public:
String floatFormat = OATPP_FLOAT_STRING_FORMAT;
/**
* Convert value to string and write to stream.

View File

@ -243,7 +243,14 @@ void Serializer::serializeObject(Serializer* serializer,
(first) ? first = false : stream->writeSimple(",", 1);
serializeString(stream, field->name, std::strlen(field->name), serializer->m_config->escapeFlags);
stream->writeSimple(":", 1);
auto streamFloatFormat = stream->floatFormat;
if (stream->floatFormat != field->info.format) {
streamFloatFormat = stream->floatFormat;
stream->floatFormat = field->info.format;
}
serializer->serialize(stream, value);
if (stream->floatFormat != streamFloatFormat)
stream->floatFormat = streamFloatFormat;
}
}
@ -276,6 +283,8 @@ void Serializer::serialize(data::stream::ConsistentOutputStream* stream,
void Serializer::serializeToStream(data::stream::ConsistentOutputStream* stream,
const oatpp::Void& polymorph)
{
if(m_config->floatStringFormat != stream->floatFormat)
stream->floatFormat = m_config->floatStringFormat;
if(m_config->useBeautifier) {
json::Beautifier beautifier(stream, " ", "\n");
serialize(&beautifier, polymorph);

View File

@ -113,6 +113,11 @@ public:
*/
v_uint32 escapeFlags = json::Utils::FLAG_ESCAPE_ALL;
/**
* Format of float string.
*/
oatpp::String floatStringFormat = OATPP_FLOAT_STRING_FORMAT;
};
public:
typedef void (*SerializerMethod)(Serializer*,

View File

@ -75,6 +75,8 @@ add_executable(oatppAllTests
oatpp/parser/json/mapping/DeserializerTest.hpp
oatpp/parser/json/mapping/EnumTest.cpp
oatpp/parser/json/mapping/EnumTest.hpp
oatpp/parser/json/mapping/FloatTest.cpp
oatpp/parser/json/mapping/FloatTest.hpp
oatpp/parser/json/mapping/UnorderedSetTest.cpp
oatpp/parser/json/mapping/UnorderedSetTest.hpp
oatpp/web/protocol/http/encoding/ChunkedTest.cpp

View File

@ -22,6 +22,7 @@
#include "oatpp/parser/json/mapping/DTOMapperPerfTest.hpp"
#include "oatpp/parser/json/mapping/DTOMapperTest.hpp"
#include "oatpp/parser/json/mapping/EnumTest.hpp"
#include "oatpp/parser/json/mapping/FloatTest.hpp"
#include "oatpp/parser/json/mapping/UnorderedSetTest.hpp"
#include "oatpp/encoding/UnicodeTest.hpp"
@ -123,6 +124,8 @@ void runTests() {
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::EnumTest);
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::FloatTest);
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::UnorderedSetTest);
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DeserializerTest);

View File

@ -0,0 +1,123 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "FloatTest.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/macro/codegen.hpp"
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
namespace {
#include OATPP_CODEGEN_BEGIN(DTO)
class DTO_32_0 : public oatpp::DTO {
DTO_INIT(DTO_32_0, DTO)
DTO_FIELD(Float32, f32);
};
class DTO_32_1 : public oatpp::DTO {
DTO_INIT(DTO_32_1, DTO)
DTO_FIELD_INFO(f32) {
info->format = "%.2f";
}
DTO_FIELD(Float32, f32);
};
class DTO_64_0 : public oatpp::DTO {
DTO_INIT(DTO_64_0, DTO)
DTO_FIELD(Float64, f64);
};
class DTO_64_1 : public oatpp::DTO {
DTO_INIT(DTO_64_1, DTO)
DTO_FIELD_INFO(f64) {
info->format = "%.2f";
}
DTO_FIELD(Float64, f64);
};
#include OATPP_CODEGEN_END(DTO)
}
void FloatTest::onRun() {
oatpp::parser::json::mapping::ObjectMapper mapper;
OATPP_LOGI(TAG, "Serialize float: 123456.123456");
{
auto test = DTO_32_0::createShared();
test->f32 = 123456.123456;
OATPP_LOGI(TAG, "using default format...");
auto json = mapper.writeToString(test);
OATPP_LOGD(TAG, "json='%s'", json->c_str());
OATPP_ASSERT(json != "{\"f32\":123456.123456}");
OATPP_LOGI(TAG, "OK");
}
{
auto test = DTO_32_1::createShared();
test->f32 = 123456.123456;
OATPP_LOGI(TAG, "using \"%%.2f\" format...");
auto json = mapper.writeToString(test);
OATPP_LOGD(TAG, "json='%s'", json->c_str());
OATPP_ASSERT(json == "{\"f32\":123456.12}");
OATPP_LOGI(TAG, "OK");
}
{
auto test = DTO_64_0::createShared();
test->f64 = 123456.123456;// +0.2;
OATPP_LOGI(TAG, "using default format...");
auto json = mapper.writeToString(test);
OATPP_LOGD(TAG, "json='%s'", json->c_str());
OATPP_ASSERT(json == "{\"f64\":123456.123456}");
OATPP_LOGI(TAG, "OK");
}
{
auto test = DTO_64_1::createShared();
test->f64 = 123456.123456;
OATPP_LOGI(TAG, "using \"%%.2f\" format...");
auto json = mapper.writeToString(test);
OATPP_LOGD(TAG, "json='%s'", json->c_str());
OATPP_ASSERT(json == "{\"f64\":123456.12}");
OATPP_LOGI(TAG, "OK");
}
}
}}}}}

View File

@ -0,0 +1,42 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_test_parser_json_mapping_FloatTest_hpp
#define oatpp_test_parser_json_mapping_FloatTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
class FloatTest : public UnitTest{
public:
FloatTest():UnitTest("TEST[parser::json::mapping::FloatTest]"){}
void onRun() override;
};
}}}}}
#endif /* oatpp_test_parser_json_mapping_FloatTest_hpp */