Skip to content

Commit

Permalink
Introduce new Json library Glaze
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Sep 29, 2024
1 parent a8b0580 commit f4f7243
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 80 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clang-format-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
formatting-check:
name: Formatting Check
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Run clang-format style check for C/C++ programs.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

permissions:
actions: read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
docker:
name: Docker build
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
matrix:
with-tests: [0, 1]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu-clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
ubuntu-clang-tidy-build:
name: Build on Ubuntu with clang-tidy checks
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
matrix:
clang-version: [19]
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/ubuntu-special.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ on:
jobs:
ubuntu-special-build:
name: Build on Ubuntu with monitoring / protobuf support
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
compiler: [g++-11]
buildmode: [Debug]
build-special-from-source: [0, 1]
prometheus-options: ["-DBUILD_SHARED_LIBS=ON -DENABLE_PULL=OFF -DENABLE_PUSH=ON -DENABLE_COMPRESSION=OFF -DENABLE_TESTING=OFF"]
Expand All @@ -25,7 +24,6 @@ jobs:
run: |
sudo apt update
sudo apt install cmake libssl-dev git libcurl4-openssl-dev ninja-build -y --no-install-recommends
echo "CC=$(echo ${{matrix.compiler}} | sed -e 's/^g++/gcc/' | sed 's/+//g')" >> $GITHUB_ENV
- name: Install prometheus-cpp
run: |
Expand All @@ -39,14 +37,12 @@ jobs:
sudo cmake --install _build
env:
CXX: ${{matrix.compiler}}
CMAKE_BUILD_TYPE: ${{matrix.buildmode}}
if: matrix.build-special-from-source == 0

- name: Configure CMake
run: cmake -S . -B build -DCCT_BUILD_PROMETHEUS_FROM_SRC=${{matrix.build-special-from-source}} -DCCT_ENABLE_PROTO=${{matrix.build-special-from-source}} -DCCT_ENABLE_ASAN=OFF -GNinja
env:
CXX: ${{matrix.compiler}}
CMAKE_BUILD_TYPE: ${{matrix.buildmode}}

- name: Build
Expand Down
12 changes: 2 additions & 10 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ on:
jobs:
ubuntu-build:
name: Build on Ubuntu
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
matrix:
compiler: [g++-11, clang++-18]
compiler: [g++-13, clang++-18]
buildmode: [Debug, Release]

steps:
Expand All @@ -25,14 +25,6 @@ jobs:
sudo apt install cmake libssl-dev libcurl4-openssl-dev ninja-build -y --no-install-recommends
echo "CC=$(echo ${{matrix.compiler}} | sed -e 's/^g++/gcc/' | sed 's/+//g')" >> $GITHUB_ENV
- name: Install gcc
run: |
sudo apt install ${{matrix.compiler}} -y --no-install-recommends
# Temporary workaround for libasan bug stated here: https://github.com/google/sanitizers/issues/1716
sudo sysctl vm.mmap_rnd_bits=28
if: startsWith(matrix.compiler, 'g')

- name: Install clang
run: |
CLANG_VERSION=$(echo ${{matrix.compiler}} | cut -d- -f2)
Expand Down
14 changes: 13 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ if(CCT_ENABLE_TESTS)
enable_testing()
endif()

# nlohmann_json - json library
# nlohmann_json - json container library
find_package(nlohmann_json CONFIG)
if(NOT nlohmann_json_FOUND)
FetchContent_Declare(
Expand All @@ -111,6 +111,18 @@ if(NOT nlohmann_json_FOUND)
list(APPEND fetchContentPackagesToMakeAvailable nlohmann_json)
endif()

# Glaze - fast json serialization library
find_package(glaze CONFIG)
if(NOT glaze)
FetchContent_Declare(
glaze
URL https://github.com/stephenberry/glaze/archive/refs/tags/v3.6.0.tar.gz
URL_HASH SHA256=d394fed35440bd1cb1a2aec059b967acc43fc04764ecb0915ba24b9f5a9ca0a3
)

list(APPEND fetchContentPackagesToMakeAvailable glaze)
endif()

# prometheus for monitoring support
if(CCT_BUILD_PROMETHEUS_FROM_SRC)
FetchContent_Declare(
Expand Down
19 changes: 10 additions & 9 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ But they have partial support which is sufficient to build `coincenter`.

The following compilers are known to compile `coincenter` (and are tested in the CI):

- **GCC** version >= 11
- **GCC** version >= 12
- **Clang** version >= 18
- **MSVC** version >= 19.39

Expand Down Expand Up @@ -135,14 +135,15 @@ cmake -S . -B build --preset conan-release
In all cases, they do not need to be installed. If they are not found at configure time, `cmake` will fetch sources and compile them automatically.
If you are building frequently `coincenter` you can install them to speed up its compilation.

| Library | Description | License |
| -------------------------------------------------------------- | -------------------------------------------------- | -------------------- |
| [amc](https://github.com/AmadeusITGroup/amc.git) | High performance C++ containers (maintained by me) | MIT |
| [googletest](https://github.com/google/googletest.git) | Google Testing and Mocking Framework | BSD-3-Clause License |
| [json](https://github.com/nlohmann/json) | JSON for Modern C++ | MIT |
| [spdlog](https://github.com/gabime/spdlog.git) | Fast C++ logging library | MIT |
| [prometheus-cpp](https://github.com/jupp0r/prometheus-cpp.git) | Prometheus Client Library for Modern C++ | MIT |
| [jwt-cpp](https://github.com/Thalhammer/jwt-cpp) | Creating and validating json web tokens in C++ | MIT |
| Library | Description | License |
| -------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------- |
| [amc](https://github.com/AmadeusITGroup/amc.git) | High performance C++ containers (maintained by me) | MIT |
| [googletest](https://github.com/google/googletest.git) | Google Testing and Mocking Framework | BSD-3-Clause License |
| [json container](https://github.com/nlohmann/json) | JSON for Modern C++ | MIT |
| [json serialization](https://github.com/stephenberry/glaze) | Extremely fast, in memory, JSON and interface library for modern C++ | MIT |
| [spdlog](https://github.com/gabime/spdlog.git) | Fast C++ logging library | MIT |
| [prometheus-cpp](https://github.com/jupp0r/prometheus-cpp.git) | Prometheus Client Library for Modern C++ | MIT |
| [jwt-cpp](https://github.com/Thalhammer/jwt-cpp) | Creating and validating json web tokens in C++ | MIT |

### With cmake

Expand Down
2 changes: 1 addition & 1 deletion src/api/exchanges/src/kucoinprivateapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ json PrivateQuery(CurlHandle& curlHandle, const APIKey& apiKey, HttpRequestType
strToSign.push_back('?');
strToSign.append(postData.str());
} else {
strToSign.append(postData.toJson().dump());
strToSign.append(postData.toJsonStr());
postDataFormat = CurlOptions::PostDataFormat::kJson;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/http-request/src/curlhandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ std::string_view CurlHandle::query(std::string_view endpoint, const CurlOptions
if (appendParametersInQueryStr) {
modifiedUrlOutIt = std::ranges::copy(postDataStr, modifiedUrlOutIt + 1).out;
} else if (opts.isPostDataInJsonFormat() && !postData.empty()) {
jsonStr = postData.toJson().dump();
jsonStr = postData.toJsonStr();
optsStr = jsonStr;
} else {
optsStr = postData.str();
Expand Down
23 changes: 23 additions & 0 deletions src/objects/include/currencycode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "cct_format.hpp"
#include "cct_hash.hpp"
#include "cct_invalid_argument_exception.hpp"
#include "cct_json-serialization.hpp"
#include "cct_string.hpp"
#include "toupperlower.hpp"

Expand Down Expand Up @@ -303,6 +304,28 @@ struct fmt::formatter<cct::CurrencyCode> {
};
#endif

namespace glz::detail {
template <>
struct from<JSON, cct::CurrencyCode> {
template <auto Opts>
static void op(cct::CurrencyCode &value, auto &&...args) {
char buf[cct::CurrencyCode::kMaxLen];
std::string_view str = buf;
read<JSON>::op<Opts>(str, args...);
value = str;
}
};

template <>
struct to<JSON, cct::CurrencyCode> {
template <auto Opts>
static void op(cct::CurrencyCode &value, auto &&...args) noexcept {
auto str = value.str();
write<JSON>::op<Opts>(str, args...);
}
};
} // namespace glz::detail

// Specialize std::hash<CurrencyCode> for easy usage of CurrencyCode as unordered_map key
namespace std {
template <>
Expand Down
26 changes: 25 additions & 1 deletion src/objects/include/monetaryamount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "cct_format.hpp"
#include "cct_hash.hpp"
#include "cct_json-serialization.hpp"
#include "cct_log.hpp"
#include "cct_string.hpp"
#include "currencycode.hpp"
Expand Down Expand Up @@ -46,6 +47,8 @@ class MonetaryAmount {

enum class RoundType : int8_t { kDown, kUp, kNearest };

static constexpr std::size_t kMaxNbCharsAmount = std::numeric_limits<AmountType>::digits10 + 3;

/// Constructs a MonetaryAmount with a value of 0 of neutral currency.
constexpr MonetaryAmount() noexcept : _amount(0) {}

Expand Down Expand Up @@ -344,7 +347,6 @@ class MonetaryAmount {
using UnsignedAmountType = uint64_t;

static constexpr AmountType kMaxAmountFullNDigits = ipow10(std::numeric_limits<AmountType>::digits10);
static constexpr std::size_t kMaxNbCharsAmount = std::numeric_limits<AmountType>::digits10 + 3;

void appendCurrencyStr(string &str) const {
if (!_curWithDecimals.isNeutral()) {
Expand Down Expand Up @@ -420,6 +422,28 @@ struct fmt::formatter<cct::MonetaryAmount> {
};
#endif

namespace glz::detail {
template <>
struct from<JSON, cct::MonetaryAmount> {
template <auto Opts>
static void op(cct::MonetaryAmount &value, auto &&...args) {
char buf[cct::MonetaryAmount::kMaxNbCharsAmount + cct::CurrencyCode::kMaxLen + 1];
std::string_view str = buf;
read<JSON>::op<Opts>(str, args...);
value = cct::MonetaryAmount(str);
}
};

template <>
struct to<JSON, cct::MonetaryAmount> {
template <auto Opts>
static void op(cct::MonetaryAmount &value, auto &&...args) noexcept {
auto str = value.str();
write<JSON>::op<Opts>(str, args...);
}
};
} // namespace glz::detail

namespace std {
template <>
struct hash<cct::MonetaryAmount> {
Expand Down
25 changes: 25 additions & 0 deletions src/objects/test/currencycode_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,29 @@ TEST(CurrencyCodeTest, Iterator) {
EXPECT_EQ("TEST", str);
}

struct Foo {
CurrencyCode currencyCode;

bool operator==(const Foo &) const noexcept = default;
};

TEST(CurrencyCodeTest, JsonSerialization) {
Foo foo{"DOGE"};

string buffer;
auto res = write_json(foo, buffer);

EXPECT_FALSE(res);

EXPECT_EQ(buffer, R"({"currencyCode":"DOGE"})");
}

TEST(CurrencyCodeTest, JsonDeserialization) {
auto s = read_json<Foo>(R"({"currencyCode":"DOGE"})");

ASSERT_TRUE(s.has_value());

EXPECT_EQ(s.value(), Foo{"DOGE"});
}

} // namespace cct
25 changes: 25 additions & 0 deletions src/objects/test/monetaryamount_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,4 +772,29 @@ TEST(MonetaryAmountTest, CurrentMaxNbDecimals) {
EXPECT_EQ(ma3.amount(ma3.currentMaxNbDecimals()), 389087900000000000L);
}

struct Foo {
MonetaryAmount amount;

bool operator==(const Foo &) const noexcept = default;
};

TEST(MonetaryAmountTest, JsonSerialization) {
Foo foo{MonetaryAmount("15.5DOGE")};

string buffer;
auto res = write_json(foo, buffer);

EXPECT_FALSE(res);

EXPECT_EQ(buffer, R"({"amount":"15.5 DOGE"})");
}

TEST(MonetaryAmountTest, JsonDeserialization) {
auto s = read_json<Foo>(R"({"amount":"15.5 DOGE"})");

ASSERT_TRUE(s.has_value());

EXPECT_EQ(s.value(), Foo{MonetaryAmount("15.5 DOGE")});
}

} // namespace cct
2 changes: 2 additions & 0 deletions src/tech/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ aux_source_directory(src API_TECH_SRC)
add_coincenter_library(tech STATIC ${API_TECH_SRC})

target_link_libraries(coincenter_tech PUBLIC nlohmann_json::nlohmann_json)
target_link_libraries(coincenter_tech PUBLIC glaze::glaze)

if (LINK_AMC)
target_link_libraries(coincenter_tech PUBLIC amc::amc)
endif()
Expand Down
10 changes: 10 additions & 0 deletions src/tech/include/cct_json-serialization.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <glaze/glaze.hpp>

namespace cct {

using glz::read_json;
using glz::write_json;

} // namespace cct
Loading

0 comments on commit f4f7243

Please sign in to comment.