-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathcookbook_dates4_test.cpp
136 lines (116 loc) · 4.27 KB
/
cookbook_dates4_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) Darrell Wright
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/beached/daw_json_link
//
// See cookbook/dates.md for the 4th example
//
#include "defines.h"
#include <daw/daw_read_file.h>
#include "daw/json/daw_json_link.h"
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
namespace daw::cookbook_dates4 {
using timepoint_t = std::chrono::time_point<std::chrono::system_clock,
std::chrono::milliseconds>;
struct MyClass4 {
std::string name;
timepoint_t timestamp;
};
bool operator==( MyClass4 const &lhs, MyClass4 const &rhs ) {
return std::tie( lhs.name, lhs.timestamp ) ==
std::tie( rhs.name, rhs.timestamp );
}
static DAW_CONSTEXPR std::string_view const prefix = "/Date(";
static DAW_CONSTEXPR std::string_view const suffix = ")/";
struct TimestampConverter {
DAW_CONSTEXPR timepoint_t operator( )( std::string_view sv ) const {
test_assert( sv.size( ) > ( prefix.size( ) + suffix.size( ) ),
"Unexpected date size" );
auto const sv_prefix = sv.substr( 0, prefix.size( ) );
test_assert( sv_prefix == prefix, "Unexpected date format" );
sv.remove_prefix( prefix.size( ) );
auto const sv_suffix =
sv.substr( sv.size( ) - suffix.size( ), suffix.size( ) );
test_assert( sv_suffix == suffix, "Unexpected date format" );
sv.remove_suffix( suffix.size( ) );
auto const val = daw::json::from_json<std::int64_t, true>( sv );
DAW_CONSTEXPR const auto epoch =
daw::json::datetime::civil_to_time_point( 1970, 1, 1, 0, 0, 0, 0 );
return epoch + std::chrono::seconds( val );
}
template<typename OutputIterator>
DAW_CONSTEXPR OutputIterator operator( )( OutputIterator it,
timepoint_t tp ) const {
DAW_CONSTEXPR const auto epoch =
daw::json::datetime::civil_to_time_point( 1970, 1, 1, 0, 0, 0, 0 );
// We divide by 1000 because the storage is in milliseconds
std::int64_t const seconds_since_epoch = ( tp - epoch ).count( ) / 1000;
it = daw::json::utils::copy_to_iterator( it, "/Date(" );
it = daw::json::utils::integer_to_string( it, seconds_since_epoch );
it = daw::json::utils::copy_to_iterator( it, ")/" );
return it;
}
};
template<JSONNAMETYPE name>
using json_timestamp =
daw::json::json_custom<name, timepoint_t, TimestampConverter,
TimestampConverter>;
} // namespace daw::cookbook_dates4
namespace daw::json {
template<>
struct json_data_contract<daw::cookbook_dates4::MyClass4> {
#if defined( DAW_JSON_CNTTP_JSON_NAME )
using type =
json_member_list<json_string<"name">,
daw::cookbook_dates4::json_timestamp<"timestamp">>;
#else
static constexpr char const name[] = "name";
static constexpr char const timestamp[] = "timestamp";
using type =
json_member_list<json_string<name>,
daw::cookbook_dates4::json_timestamp<timestamp>>;
#endif
static inline auto
to_json_data( daw::cookbook_dates4::MyClass4 const &value ) {
return std::forward_as_tuple( value.name, value.timestamp );
}
};
} // namespace daw::json
int main( int argc, char **argv )
#if defined( DAW_USE_EXCEPTIONS )
try
#endif
{
if( argc <= 1 ) {
puts( "Must supply path to cookbook_dates4.json file\n" );
exit( EXIT_FAILURE );
}
auto data = daw::read_file( argv[1] ).value( );
puts( data.data( ) );
auto const cls = daw::json::from_json<daw::cookbook_dates4::MyClass4>( data );
test_assert( cls.name == "Toronto", "Unexpected value" );
std::string const str = daw::json::to_json( cls );
puts( str.c_str( ) );
auto const cls4 = daw::json::from_json<daw::cookbook_dates4::MyClass4>( str );
test_assert( cls == cls4, "Unexpected round trip error" );
}
#if defined( DAW_USE_EXCEPTIONS )
catch( daw::json::json_exception const &jex ) {
std::cerr << "Exception thrown by parser: " << jex.reason( ) << '\n';
exit( 1 );
} catch( std::exception const &ex ) {
std::cerr << "Unknown exception thrown during testing: " << ex.what( )
<< '\n';
exit( 1 );
} catch( ... ) {
std::cerr << "Unknown exception thrown during testing\n";
throw;
}
#endif