Skip to content

Commit

Permalink
Align Codebase with Google C++ Style and Modern Practices (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
hankhsu1996 authored Aug 14, 2024
1 parent 1ac4ac2 commit ae48a4e
Show file tree
Hide file tree
Showing 59 changed files with 1,275 additions and 1,141 deletions.
10 changes: 7 additions & 3 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Language: Cpp
BasedOnStyle: llvm
BasedOnStyle: Google

# Regroup includes to improve readability and maintain consistent grouping.
# Reference: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#includeblocks
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"jsonrpc/.*"'
Expand All @@ -8,6 +11,7 @@ IncludeCategories:
Priority: 2
- Regex: "^<.*>"
Priority: 1
AlignAfterOpenBracket: DontAlign

# Override default settings to optimize alignment for modern C++ trailing return types.
AlignAfterOpenBracket: AlwaysBreak
AllowShortFunctionsOnASingleLine: false
BreakInheritanceList: AfterColon
64 changes: 64 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 'id' is common in JSON-RPC, so we disable the identifier length check.
# Magic numbers are acceptable here since we use a calculator as the main example.
Checks: >
-*,
google-*,
modernize-*,
readability-*,
cppcoreguidelines-*,
clang-analyzer-*,
-readability-identifier-length,
-readability-magic-numbers,
-cppcoreguidelines-avoid-magic-numbers,
CheckOptions:
# Google's naming conventions.
# See: https://gist.github.com/airglow923/1fa3bda42f2b193920d7f46ee8345e04
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.ClassMemberCase
value: lower_case
- key: readability-identifier-naming.ConstexprVariableCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariablePrefix
value: k
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.EnumConstantCase
value: CamelCase
- key: readability-identifier-naming.EnumConstantPrefix
value: k
- key: readability-identifier-naming.FunctionCase
value: CamelCase
- key: readability-identifier-naming.GlobalConstantCase
value: CamelCase
- key: readability-identifier-naming.GlobalConstantPrefix
value: k
- key: readability-identifier-naming.StaticConstantCase
value: CamelCase
- key: readability-identifier-naming.StaticConstantPrefix
value: k
- key: readability-identifier-naming.StaticVariableCase
value: lower_case
- key: readability-identifier-naming.MacroDefinitionCase
value: UPPER_CASE
- key: readability-identifier-naming.MacroDefinitionIgnoredRegexp
value: "^[A-Z]+(_[A-Z]+)*_$"
- key: readability-identifier-naming.MemberCase
value: lower_case
- key: readability-identifier-naming.PrivateMemberSuffix
value: _
- key: readability-identifier-naming.PublicMemberSuffix
value: ""
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.TypeAliasCase
value: CamelCase
- key: readability-identifier-naming.TypedefCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.IgnoreMainLikeFunctions
value: 1
7 changes: 5 additions & 2 deletions .clangd
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ CompileFlags:
- "-std=c++20"
- "-Wall"
- "-Wextra"
CompilationDatabase: build/Release

Diagnostics:
ClangTidy:
Remove: bugprone-unused-return-value
FastCheckFilter: Strict

# Disable inlay hints for designators to avoid JSON key indexing.
InlayHints:
Designators: No
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- main

jobs:
format-check:
clang-format-check:
runs-on: ubuntu-latest

steps:
Expand All @@ -18,6 +18,8 @@ jobs:

- name: Run clang-format
uses: jidicula/[email protected]
with:
clang-format-version: 18

build-and-test-cmake:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -47,6 +49,7 @@ jobs:
run: |
conan profile detect --force
conan install . --build=missing
conan install . -s build_type=Debug --build=missing
- name: Configure CMake and build project
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ CMakeLists.txt.user
CTestTestfile.cmake
Makefile
build/
compile_commands.json

# Bazel output directories
bazel-*
Expand Down
5 changes: 5 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
filegroup(
name = "clang_tidy_config",
srcs = [".clang-tidy"],
visibility = ["//visibility:public"],
)
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,15 @@ target_link_libraries(framed_socket_client PRIVATE jsonrpc)
add_executable(framed_socket_server examples/framed_socket_server.cpp)
target_link_libraries(framed_socket_server PRIVATE jsonrpc)

# Ensure compile_commands.json is moved after build
add_custom_command(
TARGET jsonrpc PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_SOURCE_DIR}/compile_commands.json
COMMENT "Copying compile_commands.json to source directory"
VERBATIM
)

enable_testing()
add_subdirectory(tests)
16 changes: 16 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,19 @@ http_archive(
strip_prefix = "thread-pool-4.1.0",
urls = ["https://github.com/bshoshany/thread-pool/archive/refs/tags/v4.1.0.tar.gz"],
)

http_archive(
name = "bazel_clang_tidy",
urls = ["https://github.com/erenon/bazel_clang_tidy/archive/43bef6852a433f3b2a6b001daecc8bc91d791b92.zip"],
strip_prefix = "bazel_clang_tidy-43bef6852a433f3b2a6b001daecc8bc91d791b92",
sha256 = "ebc23027a2e42035b6797235f6bb1400ddeb7a439c9dda1caa0fa7a06fd615e3",
)

# Hedron's Compile Commands Extractor for Bazel
# https://github.com/hedronvision/bazel-compile-commands-extractor
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
git_override(
module_name = "hedron_compile_commands",
remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
commit = "1e08f8e0507b6b6b1f4416a9a22cf5c28beaba93",
)
67 changes: 29 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@ Welcome to the **JSON-RPC 2.0 Modern C++ Library**! This library provides a ligh
### Prerequisites

- **Compiler**: Any compiler with C++20 support.
- **CMake**: Version 3.19+ (for CMake preset support).
- **Bazel**: Version 5.0+ (for Bazel module support).
- **Bazel**: Version 7.0+ (for Bzlmod support).
- **CMake**: Version 3.19+ (for CMake preset support, optional).
- **Conan**: Version 2.0+ (optional).

To include this library in your project, you can use CMake's FetchContent, Conan 2, or Bazel.
### Using Bazel

### Using CMake FetchContent
To include this library in your project with Bazel, ensure you are using Bazel 7.0 or later, as Bzlmod is enabled by default. Add the following to your `MODULE.bazel` file:

Add the following to your `CMakeLists.txt` to fetch the library:
```bazel
bazel_dep(name = "jsonrpc", version = "1.0.0")
```

### Optional: Using CMake FetchContent

If you prefer using CMake, add the library to your project with the following in your `CMakeLists.txt`:

```cmake
include(FetchContent)
Expand All @@ -36,9 +43,9 @@ FetchContent_Declare(
FetchContent_MakeAvailable(jsonrpc)
```

### Using Conan 2
### Optional: Using Conan 2

Create a `conanfile.txt` in your project directory with the following content:
For projects using Conan, create a `conanfile.txt` in your project directory with the following content:

```ini
[requires]
Expand All @@ -50,23 +57,15 @@ CMakeToolchain

```

### Using Bazel

Add the following to your `MODULE.bazel` file:

```bazel
bazel_dep(name = "jsonrpc", version = "1.0.0")
```

## 📖 Usage and Examples

### Creating a JSON-RPC Server

Here’s how to create a simple JSON-RPC server:

```cpp
using namespace jsonrpc::server;
using namespace jsonrpc::transport;
using jsonrpc::server::Server;
using jsonrpc::transport::StdioTransport;
using Json = nlohmann::json;

// Create a server with an stdio transport
Expand Down Expand Up @@ -94,8 +93,8 @@ To register a method, you need to provide a function that takes optional `Json`
Here’s how to create a JSON-RPC client:
```cpp
using namespace jsonrpc::client;
using namespace jsonrpc::transport;
using jsonrpc::client::Client;
using jsonrpc::transport::StdioTransport;
using Json = nlohmann::json;
// Create a client with a standard I/O transport
Expand All @@ -114,22 +113,18 @@ These examples demonstrate the basic usage of setting up a JSON-RPC server and c

## 🛠️ Developer Guide

To build and test the project, follow these steps. Bazel is the preferred method.
Follow these steps to build, test, and set up your development environment. Bazel is the preferred method.

### Option 1: Using Bazel (Preferred)

**Step 1: Build the Project**

Simply run:

```bash
bazel build //...
```

**Step 2: Run Tests**

To run all tests:

```bash
bazel test //...
```
Expand All @@ -138,24 +133,13 @@ bazel test //...

**Step 1: Install Dependencies**

Ensure you have a Conan profile configured. If the default profile (`.conan2/profiles/default`) is missing, create it:

```bash
conan profile detect --force
```

Next, install dependencies and generate `ConanPresets.json`:

```bash
conan install . --build=missing
conan install . -s build_type=Debug --build=missing
```

**Step 2: Configure and Build the Project**

Use CMake presets to configure and build the project. Ensure CMake 3.19+ is installed.

For Release configuration:
**Step 2: Configure and Build**

```bash
cmake --preset release
Expand All @@ -164,8 +148,6 @@ cmake --build --preset release

**Step 3: Run Tests**

Run tests using the appropriate CMake preset:

```bash
ctest --preset release
```
Expand All @@ -180,6 +162,15 @@ cmake --build --preset debug
ctest --preset debug
```

### Compilation Database

Generate the `compile_commands.json` file for tools like `clang-tidy` and `clangd`:

- **Bazel**: Run `bazel run @hedron_compile_commands//:refresh_all`.
- **CMake**: Simply build the project. The database will be generated automatically.

In both cases, the `compile_commands.json` file will be placed in the root directory.

## 🤝 Contributing

We welcome contributions! If you have suggestions or find any issues, feel free to open an issue or pull request.
Expand Down
32 changes: 20 additions & 12 deletions examples/calculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,32 @@
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>

using Json = nlohmann::json;
const int kDivideByZeroErrorCode = -32602;

class Calculator {
public:
Json Add(const Json &params) {
public:
static auto Add(const nlohmann::json &params) -> nlohmann::json {
spdlog::debug("Received add request with params: {}", params.dump());
double a = params["a"];
double b = params["b"];
return {{"result", a + b}};

double a_double = params["a"];
double b_double = params["b"];

return {{"result", a_double + b_double}};
}

Json Divide(const Json &params) {
static auto Divide(const nlohmann::json &params) -> nlohmann::json {
spdlog::debug("Received divide request with params: {}", params.dump());
double a = params["a"];
double b = params["b"];
if (b == 0) {
return {{"error", {{"code", -32602}, {"message", "Division by zero"}}}};

double a_double = params["a"];
double b_double = params["b"];

if (b_double == 0) {
return {
{"error",
{{"code", kDivideByZeroErrorCode},
{"message", "Division by zero"}}}};
}
return {{"result", a / b}};

return {{"result", a_double / b_double}};
}
};
Loading

0 comments on commit ae48a4e

Please sign in to comment.