[website] refactor website and docs (#263)

This commit is contained in:
sunflower-knight 2023-04-17 11:18:03 +08:00 committed by GitHub
parent 8cd8552b79
commit fb38ad3790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
108 changed files with 2593 additions and 996 deletions

View File

@ -20,6 +20,9 @@ concurrency:
group: "pages"
cancel-in-progress: true
env:
websiteDir: "${{github.workspace}}/website"
jobs:
# Single deploy job since we're just deploying
deploy:
@ -28,26 +31,26 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Install
run: sudo apt-get install doxygen graphviz
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Clone doxygen-awesome-css
run: git clone https://github.com/jothepro/doxygen-awesome-css.git
working-directory: ${{github.workspace}}
- name: Install package
run: sudo apt-get install doxygen graphviz
- name: Yarn Install
run: yarn install
working-directory: ${{github.workspace}}
working-directory: ${{env.websiteDir}}
- name: Clone doxygen-awesome-css
run: git clone https://github.com/jothepro/doxygen-awesome-css.git
working-directory: ${{env.websiteDir}}
- name: Build Website
run: bash gen_doc.sh ${{github.workspace}}
working-directory: ${{github.workspace}}
run: bash generate.sh
working-directory: ${{env.websiteDir}}
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload entire repository
path: 'docs'
path: 'website/dist'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

View File

@ -323,14 +323,6 @@ see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
5. Get approved and merged.
# Discussion group
DingTalk group
<center>
<img src="./src/coro_rpc/doc/images/yalantinglibs_ding_talk_group.png" alt="dingtalk" width="200" height="200" align="bottom" />
</center>
# License
yaLanTingLibs is distributed under the Apache License (Version 2.0)

View File

@ -1,47 +0,0 @@
set -e
ROOT_DIR=$(pwd)
rm -rf docs
mkdir docs
cd website
rm -rf guide
mkdir guide
cd guide
cp ../how-to-use-as-git-submodule.md how-to-use-as-git-submodule.md
cp ../how-to-use-by-cmake-find_package.md how-to-use-by-cmake-find_package.md
cp ../../README.md what-is-yalantinglibs.md
cp ../../src/struct_pack/doc/Introduction_EN.md struct-pack-intro.md
cp ../../src/struct_pack/doc/struct_pack_layout_EN.md struct-pack-layout.md
cp ../../src/struct_pack/doc/struct_pack_type_system_EN.md struct-pack-type-system.md
cp ../../src/struct_pb/doc/*.md .
cp ../../src/coro_rpc/doc/coro_rpc_introduction_en.md coro-rpc-intro.md
mkdir -p src/coro_rpc/doc/images
cp ../../src/coro_rpc/doc/images/yalantinglibs_ding_talk_group.png src/coro_rpc/doc/images
rm -rf images
mkdir images
cd images
cp -r ../../../src/struct_pack/doc/images/* .
cp -r ../../../src/struct_pb/doc/images/* .
cp -r ../../../src/coro_rpc/doc/images/* .
cd ../..
rm -rf zh
mkdir zh
cd zh
mkdir guide
cd guide
cp ../../../README.md what-is-yalantinglibs.md
cp ../../../src/struct_pack/doc/Introduction_CN.md struct-pack-intro.md
cp ../../../src/struct_pack/doc/struct_pack_type_system_CN.md struct-pack-type-system.md
cp ../../../src/struct_pack/doc/struct_pack_layout_CN.md struct-pack-layout.md
cp ../../../src/coro_rpc/doc/coro_rpc_introduction_cn.md coro-rpc-intro.md
cp -r ../../guide/images .
cp -r ../../guide/src .
cd "$ROOT_DIR" || exit 1
yarn docs:build
doxygen Doxyfile
doxygen Doxyfile_cn
echo 'Generate Done!'

8
website/.gitignore vendored
View File

@ -1,4 +1,4 @@
guide
images
zh
dist
node_modules
dist
cache
doxygen-awesome-css

View File

@ -1,131 +0,0 @@
export default {
lang: 'en-US',
title: 'yalantinglibs',
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
base: '/yalantinglibs/',
lastUpdated: true,
ignoreDeadLinks: false,
outDir: "../docs",
locales: {
"/": {
lang: 'en-US',
title: 'yalantinglibs',
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
},
"/zh/": {
lang: 'zh-CN',
title: '雅兰亭库',
description: 'C++20程序库包含async_simple, coro_rpc and struct_pack.',
},
},
head: [],
themeConfig: {
nav: nav(),
sidebar: {
"/guide/": sidebarGuide(),
'/zh/guide/': sidebarGuideZh(),
},
socialLinks: [
{icon: 'github', link: 'https://github.com/alibaba/yalantinglibs'}
],
footer: {
message: 'This website is released under the MIT License.',
copyright: 'Copyright © 2022 yalantinglibs contributors'
},
}
}
function nav() {
return [
{text: 'Guide', link: '/guide/what-is-yalantinglibs', activeMatch: '/guide/'},
{
text: "Language",
items: [
{
text: "English", link: "/guide/what-is-yalantinglibs"
},
{
text: "简体中文", link: '/zh/guide/what-is-yalantinglibs'
}
]
},
{
text: 'Github Issues',
link: 'https://github.com/alibaba/yalantinglibs/issues'
}
]
}
function sidebarGuide() {
return [
{
text: 'how to use?',
collapsible: true,
items: [
{text: 'Use as Git Submodule', link: '/guide/how-to-use-as-git-submodule'},
{text: 'Use by CMake find_package', link: '/guide/how-to-use-by-cmake-find_package'}
]
},
{
text: 'struct_pack',
collapsible: true,
items: [
{text: 'What is struct_pack?', link: '/guide/struct-pack-intro'},
{text: 'struct_pack layout', link: '/guide/struct-pack-layout'},
{text: 'struct_pack type system', link: '/guide/struct-pack-type-system'},
{
text: 'API Reference',
link: "https://alibaba.github.io/yalantinglibs/en/html/group__struct__pack.html"
}
]
},
{
text: 'struct_pb',
collapsible: true,
items: [
{text: 'What is struct_pb?', link: '/guide/struct-pb-intro'},
{text: 'Quick Start', link: '/guide/struct-pb-quick-start'},
{text: 'Supported Features', link: '/guide/struct-pb-supported-features'},
{text: 'Guide (proto3)', link: '/guide/struct-pb-guide-proto3'},
{text: 'Generating your struct', link: '/guide/struct-pb-generating-your-struct'},
{text: 'struct_pb API', link: '/guide/struct-pb-api'},
]
},
{
text: 'coro_rpc',
collapsible: true,
items: [
{text: 'What is coro_rpc?', link: '/guide/coro-rpc-intro'},
]
}
]
}
function sidebarGuideZh() {
return [
{
text: 'struct_pack',
collapsible: true,
items: [
{text: 'struct_pack简介', link: '/zh/guide/struct-pack-intro'},
{text: 'struct_pack类型系统', link: '/zh/guide/struct-pack-type-system'},
{text: 'struct_pack布局', link: '/zh/guide/struct-pack-layout'},
{
text: 'API Reference',
link: "https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html"
}
]
},
{
text: 'coro_rpc',
collapsible: true,
items: [
{text: 'coro_rpc简介', link: '/zh/guide/coro-rpc-intro'},
]
}
]
}

View File

@ -0,0 +1,33 @@
export const guidLinks = [
{text: 'Introduce YalantingLibs', link: '/guide/what_is_yalantinglibs'},
{text: 'Use as Git Submodule', link: '/guide/how_to_use_as_git_submodule'},
{text: 'Use by CMake find_package', link: '/guide/how_to_use_by_cmake_find_package'},
];
//构建系统相关语法
export const struct_pb_Links = [
{text: 'What is struct_pb?', link: '/struct_pb/struct_pb_intro'},
{text: 'Quick Start', link: '/struct_pb/struct_pb_quick_start'},
{text: 'Supported Features', link: '/struct_pb/struct_pb_supported_features'},
{text: 'Guide (proto3)', link: '/struct_pb/struct_pb_guide_proto3'},
{text: 'Generating your struct', link: '/struct_pb/struct_pb_generating_your_struct'},
{text: 'struct_pb API', link: '/struct_pb/struct_pb_api'},
];
export const struct_pack_Links = [
{text: 'What is struct_pack?', link: '/struct_pack/struct_pack_intro'},
{text: 'struct_pack layout', link: '/struct_pack/struct_pack_layout'},
{text: 'struct_pack type system', link: '/struct_pack/struct_pack_type_system'},
{text: 'API Reference', link: "https://alibaba.github.io/yalantinglibs/doxygen_en/html/group__struct__pack.html"}
];
export const coro_rpc_Links = [
{text: 'What is coro_rpc?', link: '/coro_rpc/coro_rpc_introduction'},
];
export const aboutLinks = [
{text: 'purecpp', link: '/about/community'},
{text: 'contribute', link: '/about/contribute'},
{text: 'community', link: '/about/teams'},
{text: 'team', link: '/about/yalantingUser'},
];

View File

@ -0,0 +1,30 @@
import {LocaleSpecificConfig, DefaultTheme} from 'vitepress';
import * as data from './en_data'
export const en_themeConfig = <DefaultTheme.Config>
{
nav: [
{text: 'Guide', link: data.guidLinks[0].link},
{text: 'Issues', link: 'https://github.com/alibaba/yalantinglibs/issues'}
],
sidebar: [
{text: 'guide', items: data.guidLinks,},
{text: 'struct_pack', items: data.struct_pack_Links,},
{text: 'struct_pb', items: data.struct_pb_Links,},
{text: 'coro_rpc', items: data.coro_rpc_Links},
]
};
export const en_LocaleConfig = <LocaleSpecificConfig>{
label: 'english',
lang: 'en-US',
title: 'yalantinglibs',
description: 'A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.',
// titleTemplate?: string | boolean
// head?: HeadConfig[]
themeConfig:en_themeConfig,
};

View File

@ -0,0 +1,35 @@
import {defineConfig} from "vitepress";
import {en_LocaleConfig} from "./en_locale";
import {zh_LocaleConfig} from "./zh_locale";
export default defineConfig(
{
//Resource
srcDir: "docs",
outDir: "dist",
//Website
base: '/yalantinglibs/',
//Article
lastUpdated: true,
ignoreDeadLinks: false,
head: [],
//Common theme config
themeConfig: {
logo: '/icon/logo.svg',
socialLinks: [
{icon: 'github', link: 'https://github.com/alibaba/yalantinglibs'}
],
footer: {
message: 'This website is released under the MIT License.',
copyright: 'Copyright © 2022 yalantinglibs contributors'
},
},
//Locales config and theme-specify
locales: {
'root': <any>en_LocaleConfig,
'zh': <any>zh_LocaleConfig,
},
}
)

View File

@ -0,0 +1,33 @@
export const guidLinks = [
{text: 'Introduce YalantingLibs', link: '/zh/guide/what_is_yalantinglibs'},
{text: 'Use as Git Submodule', link: '/zh/guide/how_to_use_as_git_submodule'},
{text: 'Use by CMake find_package', link: '/zh/guide/how_to_use_by_cmake_find_package'},
];
//构建系统相关语法
export const struct_pb_Links = [
{text: 'What is struct_pb?', link: '/zh/struct_pb/struct_pb_intro'},
{text: 'Quick Start', link: '/zh/struct_pb/struct_pb_quick_start'},
{text: 'Supported Features', link: '/zh/struct_pb/struct_pb_supported_features'},
{text: 'Guide (proto3)', link: '/zh/struct_pb/struct_pb_guide_proto3'},
{text: 'Generating your struct', link: '/zh/struct_pb/struct_pb_generating_your_struct'},
{text: 'struct_pb API', link: '/zh/struct_pb/struct_pb_api'},
];
export const struct_pack_Links = [
{text: 'What is struct_pack?', link: '/zh/struct_pack/struct_pack_intro'},
{text: 'struct_pack layout', link: '/zh/struct_pack/struct_pack_layout'},
{text: 'struct_pack type system', link: '/zh/struct_pack/struct_pack_type_system'},
{text: 'API Reference', link: "https://alibaba.github.io/yalantinglibs/doxygen_cn/html/group__struct__pack.html"}
];
export const coro_rpc_Links = [
{text: 'What is coro_rpc?', link: '/zh/coro_rpc/coro_rpc_introduction'},
];
export const aboutLinks = [
{text: 'purecpp', link: '/zh/about/community'}, //TODO 未来支持英语
{text: 'contribute', link: '/zh/about/contribute'},
{text: 'community', link: '/zh/about/teams'},
{text: 'team', link: '/zh/about/yalantingUser'},
];

View File

@ -0,0 +1,28 @@
import {LocaleSpecificConfig, DefaultTheme} from 'vitepress'
import * as data from './zh_data'
export const zh_themeConfig = <DefaultTheme.Config>
{
nav: [
{text: '指南', link: data.guidLinks[0].link},
{text: 'Issues', link: 'https://github.com/alibaba/yalantinglibs/issues'}
],
sidebar: [
{text: '指南', items: data.guidLinks,},
{text: 'struct_pack', items: data.struct_pack_Links,},
{text: 'struct_pb', items: data.struct_pb_Links,},
{text: 'coro_rpc', items: data.coro_rpc_Links},
]
};
export const zh_LocaleConfig = <LocaleSpecificConfig>{
label: '简体中文',
lang: 'zh-CN',
title: '雅兰亭库',
description: '中文简介待补充',
// titleTemplate?: string | boolean
// head?: HeadConfig[]
themeConfig:zh_themeConfig
};

View File

@ -1,9 +1,11 @@
PROJECT_NAME=yaLanTingLibs
GENERATE_HTML=yes
GENERATE_LATEX=no
INPUT=include/struct_pack include/coro_rpc include/coro_rpc/coro_rpc \
include/struct_pack/struct_pack/struct_pack_impl.hpp \
src/coro_rpc/doc/coro_rpc_introduction_EN.md
INPUT=../include/struct_pack \
../include/coro_rpc \
../include/coro_rpc/coro_rpc \
../include/struct_pack/struct_pack/struct_pack_impl.hpp \
docs/coro_rpc/coro_rpc_introduction.md
GENERATE_TREEVIEW = YES # required!
DISABLE_INDEX = NO
@ -19,8 +21,8 @@ HTML_EXTRA_FILES = doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
HTML_HEADER = header.html
IMAGE_PATH = src/coro_rpc/doc/images src/struct_pack/doc/images
EXAMPLE_PATH = src/coro_rpc/examples
HTML_HEADER = doxy/header.html
IMAGE_PATH = docs/coro_rpc/images docs/struct_pack/images
EXAMPLE_PATH = ../src/coro_rpc/examples
EXAMPLE_RECURSIVE = YES
OUTPUT_DIRECTORY = docs/en
OUTPUT_DIRECTORY = dist/doxygen_en

View File

@ -1,10 +1,10 @@
PROJECT_NAME=yaLanTingLibs
GENERATE_HTML=yes
GENERATE_LATEX=no
INPUT=src/coro_rpc/doc/coro_rpc_doc.hpp \
src/coro_rpc/doc/coro_rpc_introduction_cn.md \
src/struct_pack/doc/struct_pack_doc.hpp \
src/struct_pack/doc/Introduction_CN.md
INPUT=docs/zh/coro_rpc/coro_rpc_doc.hpp \
docs/zh/coro_rpc/coro_rpc_intro.md \
docs/zh/struct_pack/struct_pack_doc.hpp \
docs/zh/struct_pack/struct_pack_intro.md
GENERATE_TREEVIEW = YES # required!
DISABLE_INDEX = NO
@ -20,9 +20,9 @@ HTML_EXTRA_FILES = doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
doxygen-awesome-css/doxygen-awesome-paragraph-link.js \
doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js \
doxygen-awesome-css/doxygen-awesome-interactive-toc.js
HTML_HEADER = header.html
IMAGE_PATH = src/coro_rpc/doc/images src/struct_pack/doc/images
EXAMPLE_PATH = src/coro_rpc/examples
HTML_HEADER = doxy/header.html
IMAGE_PATH = docs/coro_rpc/images docs/struct_pack/images
EXAMPLE_PATH = ../src/coro_rpc/examples
EXAMPLE_RECURSIVE = YES
OUTPUT_LANGUAGE = Chinese
OUTPUT_DIRECTORY = docs/cn
OUTPUT_DIRECTORY = dist/doxygen_cn

View File

@ -66,6 +66,6 @@ finished...
Done!
```
the config of vitepress is `website/.vitepress/config.ts`
the config of vitepress is `website/.vitepress/config/index.ts`
the config of doxygen is `Doxyfile` and `Doxyfile_cn`

View File

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

View File

@ -0,0 +1,330 @@
<p align="center">
<h1 align="center">yaLanTingLibs</h1>
<h6 align="center">A Collection of C++20 libraries, include struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and async_simple </h6>
</p>
<p align="center">
<img alt="license" src="https://img.shields.io/github/license/alibaba/async_simple?style=flat-square">
<img alt="language" src="https://img.shields.io/github/languages/top/alibaba/yalantinglibs?style=flat-square">
<img alt="last commit" src="https://img.shields.io/github/last-commit/alibaba/async_simple?style=flat-square">
</p>
yaLanTingLibs is a collection of C++20 libraries, now it contains struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and [async_simple](https://github.com/alibaba/async_simple), more and more cool libraries will be added into yaLanTingLibs(such as http.) in the future.
The target of yaLanTingLibs: provide very easy and high performance C++20 libraries for C++ developers, it can help to quickly build high performance applications.
| OS (Compiler Version) | Status |
|------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| Ubuntu 22.04 (clang 14.0.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/linux_clang.yml/badge.svg?branch=main) |
| Ubuntu 22.04 (gcc 11.2.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/linux_gcc.yml/badge.svg?branch=main) |
| macOS Monterey 12 (AppleClang 14.0.0.14000029) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/mac.yml/badge.svg?branch=main) |
| Windows Server 2022 (MSVC 19.33.31630.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/windows.yml/badge.svg?branch=main) |
## coro_rpc
Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene. coro_rpc is a header only library.
You can finish a rpc server and rpc client in 5 minutes!
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/coro-rpc-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/coro-rpc-intro.html)
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__coro__rpc.html)
[Talk](https://alibaba.github.io/yalantinglibs/coro_rpc_introduction_purecpp_talk.pdf) of coro_rpc on purecpp conference.
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 04:55:08 of the video record.
### quick example
1.define a rpc function as a local normal function.
```cpp
// rpc_service.hpp
inline std::string_view echo(std::string_view str) { return str; }
```
2.register rpc function and start a server
```cpp
#include "rpc_service.hpp"
#include <coro_rpc/coro_rpc_server.hpp>
int main() {
coro_rpc_server server(/*thread_num =*/10, /*port =*/9000);
server.register_handler<echo>(); // register function echo
server.start(); // start the server & block
}
```
3.rpc client call rpc service
```cpp
#include "rpc_service.hpp"
#include <coro_rpc/coro_rpc_client.hpp>
Lazy<void> test_client() {
coro_rpc_client client;
co_await client.connect("localhost", /*port =*/"9000"); // connect to the server
auto r = co_await client.call<echo>("hello coro_rpc"); // call remote function echo
std::cout << r.result.value() << "\n"; //will print "hello coro_rpc"
}
int main() {
syncAwait(test_client());
}
```
More examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/coro_rpc/examples).
## struct_pack
Based on compile-time reflection, very easy to use, high performance serialization library, struct_pack is a header only library, it is used by coro_rpc now.
Only one line code to finish serialization and deserialization, 10-50x faster than protobuf.
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/struct-pack-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/struct-pack-intro.html)
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html)
[(Slides) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://alibaba.github.io/yalantinglibs/A%20Faster%20Serialization%20Library%20Based%20on%20Compile-time%20Reflection%20and%20C++%2020.pdf) of struct_pack on CppCon2022
[Slides](https://alibaba.github.io/yalantinglibs/struct_pack_introduce_CN.pdf) of struct_pack on purecpp conference.
[(Video) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://www.youtube.com/watch?v=myhB8ZlwOlE) on cppcon2022
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 01:32:20 of the video record.
### quick example
```cpp
struct person {
int64_t id;
std::string name;
int age;
double salary;
};
person person1{.id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42};
// one line code serialize
std::vector<char> buffer = struct_pack::serialize(person1);
// one line code deserialization
auto person2 = deserialize<person>(buffer);
```
See more examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/struct_pack/examples).
## struct_json
reflection-based json lib, very easy to do struct to json and json to struct.
### quick example
```cpp
#include "struct_json/json_reader.h"
#include "struct_json/json_writer.h"
struct person {
std::string name;
int age;
};
REFLECTION(person, name, age);
int main() {
person p{.name = "tom", .age = 20};
std::string str;
struct_json::to_json(p, str); // {"name":"tom","age":20}
person p1;
struct_json::from_json(p1, str);
}
```
## coro_http_client
coro_http_client is a C++20 coroutine http(https) client, include: get/post, websocket, multipart file upload, chunked and ranges download etc.
### get/post
```cpp
#include "coro_http/coro_http_client.h"
using namespace ylt;
async_simple::coro::Lazy<void> get_post(coro_http_client &client) {
std::string uri = "http://www.example.com";
auto result = co_await client.async_get(uri);
std::cout << result.status << "\n";
result = co_await client.async_post(uri, "hello", req_content_type::string);
std::cout << result.status << "\n";
}
int main() {
coro_http_client client{};
async_simple::coro::syncAwait(get_post(client));
}
```
### websocket
```cpp
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
client.on_ws_close([](std::string_view reason) {
std::cout << "web socket close " << reason << std::endl;
});
client.on_ws_msg([](resp_data data) {
std::cout << data.resp_body << std::endl;
});
// connect to your websocket server.
bool r = co_await client.async_connect("ws://example.com/ws");
if (!r) {
co_return;
}
co_await client.async_send_ws("hello websocket");
co_await client.async_send_ws("test again", /*need_mask = */ false);
co_await client.async_send_ws_close("ws close reason");
}
```
### upload/download
```cpp
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
std::string uri = "http://example.com";
client.add_str_part("hello", "world");
client.add_str_part("key", "value");
client.add_file_part("test", "test.jpg");
auto result = co_await client.async_upload(uri);
std::cout << result.status << "\n";
result = co_await client.async_upload(uri, "test", "test.jpg");
}
async_simple::coro::Lazy<void> download_files(coro_http_client &client) {
// chunked download
auto result = co_await client.async_download("http://example.com/test.jpg",
"myfile.jpg");
std::cout << result.status << "\n";
// ranges download
result = co_await client.async_download("http://example.com/test.txt",
"myfile.txt", "1-10,11-16");
std::cout << result.status << "\n";
}
```
## async_simple
A C++ 20 coroutine library offering simple, light-weight and easy-to-use components to write asynchronous codes.
See [async_simple](https://github.com/alibaba/async_simple)
## compiler requirements
make sure you have such compilers:
- clang11 and libstdc++-8 above;
- or gcc10 and g++10 above;
- or msvc2019 above
## Quick Start
- clone repo
```shell
git clone https://github.com/alibaba/yalantinglibs.git
```
- build & install
```shell
cd yalantinglibs
mkdir build && cd build
cmake ..
# You can use those option to skip build unit-test & benchmark & example:
# cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_BENCHMARK=OFF -DBUILD_UNIT_TESTS=OFF
make
make install
```
- run tests
```shell
ctest .
```
- start your coding
### coro_rpc
```shell
cd yalantinglibs/src/coro_rpc/examples/helloworld
mkdir build && cd build
cmake ..
make
# For more detail, see Cmakelist.txt in helloworld.
```
### struct_pack
TODO
## Benchmark
options:
```bash
./benchmark_client [threads] [client_pre_thread] [pipeline_size] [host] [port] [test_data_path] [test_time] [warm_up_time]
```
## Build Options
| option | description | default |
| ----------------- | ------------------------------------------------ | ------- |
| CMAKE_BUILD_TYPE | build type | Release |
| BUILD_WITH_LIBCXX | Build with libc++ | OFF |
| BUILD_EXAMPLES | Build examples | ON |
| BUILD_BENCHMARK | Build benchmark | ON |
| BUILD_UNIT_TESTS | Build unit test | ON |
| USE_CONAN | Use conan package manager to handle dependencies | OFF |
| ENABLE_SSL | Enable ssl support | OFF |
| ENABLE_IO_URING | Enable io_uring support | OFF |
## Dependencies
We use doctest for unit test.
All third-party dependencies are put in include/thirdparty.
### coro_rpc
- [struct_pack](https://github.com/alibaba/yalantinglibs)
- [easylog](https://github.com/alibaba/yalantinglibs)
- [asio](https://github.com/chriskohlhoff/asio)
- openssl (optional)
### struct_pack
No dependency.
### struct_json
- [iguana](https://github.com/qicosmos/iguana)
### struct_pb
TODO
### easylog
No dependency.
# How to generate document
see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
# How to Contribute
1. Create an issue in the issue template.
2. Run tests and `git-clang-format HEAD^` locally for the change.
3. Create a PR, fill in the PR template.
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
5. Get approved and merged.
# License
yaLanTingLibs is distributed under the Apache License (Version 2.0)
This product contains various third-party components under other open-source licenses.
See the NOTICE file for more information.

View File

@ -10,7 +10,7 @@ hero:
actions:
- theme: brand
text: Get Started
link: /guide/what-is-yalantinglibs
link: /guide/what_is_yalantinglibs
- theme: alt
text: View on GitHub
link: https://github.com/alibaba/yalantinglibs.git
@ -22,4 +22,4 @@ features:
details: Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene.
- title: struct_json
details: Reflection-based json lib, very easy to do struct to json and json to struct.
---
---

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -1,13 +1,13 @@
<mxfile host="65bd71144e">
<diagram id="bgBt0THlO4EiIMCifpc1" name="第 1 页">
<mxGraphModel dx="530" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="DATA_LEN" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="440" width="120" height="60" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<mxfile host="65bd71144e">
<diagram id="bgBt0THlO4EiIMCifpc1" name="第 1 页">
<mxGraphModel dx="530" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="DATA_LEN" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="440" width="120" height="60" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,34 +1,34 @@
<mxfile host="65bd71144e">
<diagram id="Pdm-2sLAR-h-lwVb3lNh" name="第 1 页">
<mxGraphModel dx="383" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="40" y="440" width="280" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="" style="endArrow=none;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="180" y="490" as="sourcePoint"/>
<mxPoint x="180" y="370" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="5" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="4" target="2">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="4" value="31 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="120" y="410" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="6" value="类型哈希" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="110" y="455" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="7" value="1 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="250" y="410" width="70" height="30" as="geometry"/>
</mxCell>
<mxCell id="8" value="选项:是否存在元信息" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="252.5" y="455" width="65" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<mxfile host="65bd71144e">
<diagram id="Pdm-2sLAR-h-lwVb3lNh" name="第 1 页">
<mxGraphModel dx="383" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="40" y="440" width="280" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="" style="endArrow=none;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="180" y="490" as="sourcePoint"/>
<mxPoint x="180" y="370" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="5" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="4" target="2">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="4" value="31 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="120" y="410" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="6" value="类型哈希" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="110" y="455" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="7" value="1 bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="250" y="410" width="70" height="30" as="geometry"/>
</mxCell>
<mxCell id="8" value="选项:是否存在元信息" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="252.5" y="455" width="65" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,22 +1,22 @@
<mxfile host="65bd71144e">
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
<mxGraphModel dx="936" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="30" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="11" y="160" width="319" height="60" as="geometry"/>
</mxCell>
<mxCell id="31" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="141" y="130" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="37" value="负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="330" y="160" width="401" height="60" as="geometry"/>
</mxCell>
<mxCell id="38" value="可变长度" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="485.5" y="130" width="90" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<mxfile host="65bd71144e">
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
<mxGraphModel dx="936" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="30" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="11" y="160" width="319" height="60" as="geometry"/>
</mxCell>
<mxCell id="31" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="141" y="130" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="37" value="负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="330" y="160" width="401" height="60" as="geometry"/>
</mxCell>
<mxCell id="38" value="可变长度" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="485.5" y="130" width="90" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -1,46 +1,46 @@
<mxfile host="65bd71144e">
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
<mxGraphModel dx="1335" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="11" y="400" width="320" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="141" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="5" value="1 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="341" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="6" value="元信息头&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="331" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="7" value="完整类型信息&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="491" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="9" value="数据总长度&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="411" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="10" value="DATA_SIZE" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="421" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="11" value="已知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="571" y="400" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="12" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="606" y="370" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="未知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="731" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="16" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="486" y="370" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="17" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="726" y="370" width="90" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<mxfile host="65bd71144e">
<diagram id="oe2Vl5H5gF7YLMPssPNC" name="第 1 页">
<mxGraphModel dx="1335" dy="917" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="类型哈希" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="11" y="400" width="320" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="4 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="141" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="5" value="1 Bytes" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="341" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="6" value="元信息头&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="331" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="7" value="完整类型信息&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="491" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="9" value="数据总长度&lt;br&gt;(可选)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="411" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="10" value="DATA_SIZE" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="421" y="370" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="11" value="已知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="571" y="400" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="12" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="606" y="370" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="未知字段负载" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="731" y="400" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="16" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="486" y="370" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="17" value="variable length" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="726" y="370" width="90" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,46 +1,46 @@
<mxfile host="65bd71144e">
<diagram id="_e0WKF2P-E546wreTLZB" name="第 1 页">
<mxGraphModel dx="1453" dy="873" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="保留给后续扩展目前应全为0" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="80" y="450" width="240" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="是否存储完整类型信息" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="480" y="450" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="4" value="DATA_SIZE&lt;br&gt;(0B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="560" y="450" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="5" value="LEN_SIZE&lt;br&gt;(1B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="320" y="450" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="6" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="370" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="7" value="1bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="490" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="8" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="610" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="9" value="3bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="170" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="10" value="" style="endArrow=classic;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" source="11" target="12" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="650" y="540" as="sourcePoint"/>
<mxPoint x="130" y="540" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="11" value="低位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="660" y="510" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="高位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="80" y="510" width="60" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<mxfile host="65bd71144e">
<diagram id="_e0WKF2P-E546wreTLZB" name="第 1 页">
<mxGraphModel dx="1453" dy="873" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="保留给后续扩展目前应全为0" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="80" y="450" width="240" height="60" as="geometry"/>
</mxCell>
<mxCell id="3" value="是否存储完整类型信息" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="480" y="450" width="80" height="60" as="geometry"/>
</mxCell>
<mxCell id="4" value="DATA_SIZE&lt;br&gt;(0B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="560" y="450" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="5" value="LEN_SIZE&lt;br&gt;(1B,2B,4B,8B)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="320" y="450" width="160" height="60" as="geometry"/>
</mxCell>
<mxCell id="6" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="370" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="7" value="1bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="490" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="8" value="2bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="610" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="9" value="3bit" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="170" y="420" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="10" value="" style="endArrow=classic;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" source="11" target="12" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="650" y="540" as="sourcePoint"/>
<mxPoint x="130" y="540" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="11" value="低位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="660" y="510" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="高位" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="80" y="510" width="60" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -251,4 +251,4 @@ class coro_rpc_client {
*/
auto &get_executor();
};
} // namespace coro_rpc
} // namespace coro_rpc

View File

@ -0,0 +1,62 @@
# Use as Git Submodule
Thanks to [@piperoc](https://github.com/piperoc), and the demo code is [here](https://github.com/PikachuHyA/yalantinglibs_as_submodule_demo).
**Step 1**: create your project directory mkdir `~/code/awesome-solution` and cd `~/code/awesome-solution`.
**Step 2**: make it a git repo by calling `git init` (this will initialize and empty git repo)
**Step 3**: add the library as a ***true submodule*** with `git submodule add https://github.com/alibaba/yalantinglibs.git` .
At this point you should have a file system structure like:
```
awesome-solution
├── .git
├── .gitmodules
└── yalantinglibs
```
**Step 4**: there are often more than one project using the library in the solution. In our demo, there would be a client app and a server app that both use the library. Those apps would be separate projects, so the file system will start looking like:
```
awesome-solution
├── CMakeLists.txt
├── client
│ ├── CMakeLists.txt
│ ├── client.cpp
│ ├── service.h
├─── server
│ ├── CMakeLists.txt
│ ├── server.cpp
│ ├── service.h
└─── yalantinglibs
```
**Step 5**: here's the root CMakeLists.txt (it's very important to set the compiler flags if you are running g++)
```cmake
cmake_minimum_required(VERSION 3.15)
project(awesome-solution LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# it's very important to set the compiler flags
# if you use gcc/g++
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
if (CMAKE_CXX_COMPILER_VERSION MATCHES "12.*")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
endif()
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(client)
add_subdirectory(server)
add_subdirectory(yalantinglibs)
```

View File

@ -0,0 +1,63 @@
# Use by CMake find_package
To use CMake find_package, CMake and yaLanTingLibs must be installed first.
And you have to use CMake to manage your project.
## Install yaLanTingLibs
Currently, only build from sources supported.
Install from package manager (e.g. conan and vcpkg) is WIP.
use the following instructions
- clone yaLanTingLibs
```shell
git clone https://github.com/alibaba/yalantinglibs.git
cd yalantinglibs
```
- build yaLanTingLibs
```shell
mkdir build && cd build
cmake ..
make -j
```
- install yaLanTingLibs
```shell
# sudo if needed
make install
```
## Use yaLanTingLibs
write `CMakeLists.txt` and use find_package
```
cmake_minimum_required(VERSION 3.15)
project(awesome-solution LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# it's very important to set the compiler flags
# if you use gcc/g++
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
if (CMAKE_CXX_COMPILER_VERSION MATCHES "12.*")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
endif()
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(Threads REQUIRED)
find_package(yalantinglibs REQUIRED)
# add your server
target_link_libraries(your_server PRIVATE yalantinglibs::coro_rpc)
```
the full demo is here: https://github.com/PikachuHyA/yalantinglibs_find_package_demo
## Reference
- [CMake find_package Document](https://cmake.org/cmake/help/latest/command/find_package.html?highlight=find_package)
- [use yaLanTingLibs with CMake find_package demo code](https://github.com/PikachuHyA/yalantinglibs_find_package_demo)
- [use yaLanTingLibs as Git Submodule demo code](https://github.com/PikachuHyA/yalantinglibs_as_submodule_demo)

View File

@ -0,0 +1,330 @@
<p align="center">
<h1 align="center">yaLanTingLibs</h1>
<h6 align="center">A Collection of C++20 libraries, include struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and async_simple </h6>
</p>
<p align="center">
<img alt="license" src="https://img.shields.io/github/license/alibaba/async_simple?style=flat-square">
<img alt="language" src="https://img.shields.io/github/languages/top/alibaba/yalantinglibs?style=flat-square">
<img alt="last commit" src="https://img.shields.io/github/last-commit/alibaba/async_simple?style=flat-square">
</p>
yaLanTingLibs is a collection of C++20 libraries, now it contains struct_pack, struct_json, struct_pb, easylog, coro_rpc, coro_http and [async_simple](https://github.com/alibaba/async_simple), more and more cool libraries will be added into yaLanTingLibs(such as http.) in the future.
The target of yaLanTingLibs: provide very easy and high performance C++20 libraries for C++ developers, it can help to quickly build high performance applications.
| OS (Compiler Version) | Status |
|------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| Ubuntu 22.04 (clang 14.0.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/linux_clang.yml/badge.svg?branch=main) |
| Ubuntu 22.04 (gcc 11.2.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/linux_gcc.yml/badge.svg?branch=main) |
| macOS Monterey 12 (AppleClang 14.0.0.14000029) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/mac.yml/badge.svg?branch=main) |
| Windows Server 2022 (MSVC 19.33.31630.0) | ![win](https://github.com/alibaba/yalantinglibs/actions/workflows/windows.yml/badge.svg?branch=main) |
## coro_rpc
Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene. coro_rpc is a header only library.
You can finish a rpc server and rpc client in 5 minutes!
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/coro-rpc-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/coro-rpc-intro.html)
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__coro__rpc.html)
[Talk](https://alibaba.github.io/yalantinglibs/coro_rpc_introduction_purecpp_talk.pdf) of coro_rpc on purecpp conference.
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 04:55:08 of the video record.
### quick example
1.define a rpc function as a local normal function.
```cpp
// rpc_service.hpp
inline std::string_view echo(std::string_view str) { return str; }
```
2.register rpc function and start a server
```cpp
#include "rpc_service.hpp"
#include <coro_rpc/coro_rpc_server.hpp>
int main() {
coro_rpc_server server(/*thread_num =*/10, /*port =*/9000);
server.register_handler<echo>(); // register function echo
server.start(); // start the server & block
}
```
3.rpc client call rpc service
```cpp
#include "rpc_service.hpp"
#include <coro_rpc/coro_rpc_client.hpp>
Lazy<void> test_client() {
coro_rpc_client client;
co_await client.connect("localhost", /*port =*/"9000"); // connect to the server
auto r = co_await client.call<echo>("hello coro_rpc"); // call remote function echo
std::cout << r.result.value() << "\n"; //will print "hello coro_rpc"
}
int main() {
syncAwait(test_client());
}
```
More examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/coro_rpc/examples).
## struct_pack
Based on compile-time reflection, very easy to use, high performance serialization library, struct_pack is a header only library, it is used by coro_rpc now.
Only one line code to finish serialization and deserialization, 10-50x faster than protobuf.
[English Introduction](https://alibaba.github.io/yalantinglibs/guide/struct-pack-intro.html) | [中文简介](https://alibaba.github.io/yalantinglibs/zh/guide/struct-pack-intro.html)
English API(TODO) | [中文API](https://alibaba.github.io/yalantinglibs/cn/html/group__struct__pack.html)
[(Slides) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://alibaba.github.io/yalantinglibs/A%20Faster%20Serialization%20Library%20Based%20on%20Compile-time%20Reflection%20and%20C++%2020.pdf) of struct_pack on CppCon2022
[Slides](https://alibaba.github.io/yalantinglibs/struct_pack_introduce_CN.pdf) of struct_pack on purecpp conference.
[(Video) A Faster Serialization Library Based on Compile-time Reflection and C++ 20](https://www.youtube.com/watch?v=myhB8ZlwOlE) on cppcon2022
[Video](https://live.csdn.net/room/csdnlive1/bKFbKP7T) on purecpp conference, start from 01:32:20 of the video record.
### quick example
```cpp
struct person {
int64_t id;
std::string name;
int age;
double salary;
};
person person1{.id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42};
// one line code serialize
std::vector<char> buffer = struct_pack::serialize(person1);
// one line code deserialization
auto person2 = deserialize<person>(buffer);
```
See more examples [here](https://github.com/alibaba/yalantinglibs/tree/main/src/struct_pack/examples).
## struct_json
reflection-based json lib, very easy to do struct to json and json to struct.
### quick example
```cpp
#include "struct_json/json_reader.h"
#include "struct_json/json_writer.h"
struct person {
std::string name;
int age;
};
REFLECTION(person, name, age);
int main() {
person p{.name = "tom", .age = 20};
std::string str;
struct_json::to_json(p, str); // {"name":"tom","age":20}
person p1;
struct_json::from_json(p1, str);
}
```
## coro_http_client
coro_http_client is a C++20 coroutine http(https) client, include: get/post, websocket, multipart file upload, chunked and ranges download etc.
### get/post
```cpp
#include "coro_http/coro_http_client.h"
using namespace ylt;
async_simple::coro::Lazy<void> get_post(coro_http_client &client) {
std::string uri = "http://www.example.com";
auto result = co_await client.async_get(uri);
std::cout << result.status << "\n";
result = co_await client.async_post(uri, "hello", req_content_type::string);
std::cout << result.status << "\n";
}
int main() {
coro_http_client client{};
async_simple::coro::syncAwait(get_post(client));
}
```
### websocket
```cpp
async_simple::coro::Lazy<void> websocket(coro_http_client &client) {
client.on_ws_close([](std::string_view reason) {
std::cout << "web socket close " << reason << std::endl;
});
client.on_ws_msg([](resp_data data) {
std::cout << data.resp_body << std::endl;
});
// connect to your websocket server.
bool r = co_await client.async_connect("ws://example.com/ws");
if (!r) {
co_return;
}
co_await client.async_send_ws("hello websocket");
co_await client.async_send_ws("test again", /*need_mask = */ false);
co_await client.async_send_ws_close("ws close reason");
}
```
### upload/download
```cpp
async_simple::coro::Lazy<void> upload_files(coro_http_client &client) {
std::string uri = "http://example.com";
client.add_str_part("hello", "world");
client.add_str_part("key", "value");
client.add_file_part("test", "test.jpg");
auto result = co_await client.async_upload(uri);
std::cout << result.status << "\n";
result = co_await client.async_upload(uri, "test", "test.jpg");
}
async_simple::coro::Lazy<void> download_files(coro_http_client &client) {
// chunked download
auto result = co_await client.async_download("http://example.com/test.jpg",
"myfile.jpg");
std::cout << result.status << "\n";
// ranges download
result = co_await client.async_download("http://example.com/test.txt",
"myfile.txt", "1-10,11-16");
std::cout << result.status << "\n";
}
```
## async_simple
A C++ 20 coroutine library offering simple, light-weight and easy-to-use components to write asynchronous codes.
See [async_simple](https://github.com/alibaba/async_simple)
## compiler requirements
make sure you have such compilers:
- clang11 and libstdc++-8 above;
- or gcc10 and g++10 above;
- or msvc2019 above
## Quick Start
- clone repo
```shell
git clone https://github.com/alibaba/yalantinglibs.git
```
- build & install
```shell
cd yalantinglibs
mkdir build && cd build
cmake ..
# You can use those option to skip build unit-test & benchmark & example:
# cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_BENCHMARK=OFF -DBUILD_UNIT_TESTS=OFF
make
make install
```
- run tests
```shell
ctest .
```
- start your coding
### coro_rpc
```shell
cd yalantinglibs/src/coro_rpc/examples/helloworld
mkdir build && cd build
cmake ..
make
# For more detail, see Cmakelist.txt in helloworld.
```
### struct_pack
TODO
## Benchmark
options:
```bash
./benchmark_client [threads] [client_pre_thread] [pipeline_size] [host] [port] [test_data_path] [test_time] [warm_up_time]
```
## Build Options
| option | description | default |
| ----------------- | ------------------------------------------------ | ------- |
| CMAKE_BUILD_TYPE | build type | Release |
| BUILD_WITH_LIBCXX | Build with libc++ | OFF |
| BUILD_EXAMPLES | Build examples | ON |
| BUILD_BENCHMARK | Build benchmark | ON |
| BUILD_UNIT_TESTS | Build unit test | ON |
| USE_CONAN | Use conan package manager to handle dependencies | OFF |
| ENABLE_SSL | Enable ssl support | OFF |
| ENABLE_IO_URING | Enable io_uring support | OFF |
## Dependencies
We use doctest for unit test.
All third-party dependencies are put in include/thirdparty.
### coro_rpc
- [struct_pack](https://github.com/alibaba/yalantinglibs)
- [easylog](https://github.com/alibaba/yalantinglibs)
- [asio](https://github.com/chriskohlhoff/asio)
- openssl (optional)
### struct_pack
No dependency.
### struct_json
- [iguana](https://github.com/qicosmos/iguana)
### struct_pb
TODO
### easylog
No dependency.
# How to generate document
see [Build Website](https://alibaba.github.io/yalantinglibs/README.html)
# How to Contribute
1. Create an issue in the issue template.
2. Run tests and `git-clang-format HEAD^` locally for the change.
3. Create a PR, fill in the PR template.
4. Choose one or more reviewers from contributors: (e.g., qicosmos, poor-circle, PikachuHyA).
5. Get approved and merged.
# License
yaLanTingLibs is distributed under the Apache License (Version 2.0)
This product contains various third-party components under other open-source licenses.
See the NOTICE file for more information.

25
website/docs/zh/index.md Normal file
View File

@ -0,0 +1,25 @@
---
layout: home
title: 雅兰亭库
titleTemplate: A collection of C++20 libraries, include async_simple, coro_rpc and struct_pack.
hero:
name: 雅兰亭库
text: A collection of C++20 libraries.
actions:
- theme: brand
text: 快速开始
link: /zh/guide/what_is_yalantinglibs
- theme: alt
text: 开源仓库
link: https://github.com/alibaba/yalantinglibs.git
features:
- title: struct_pack
details: 只需要一行代码完成序列化和反序列化, 比 protobuf 快 10-50 倍.
- title: coro_rpc
details: Very easy-to-use, coroutine-based, high performance rpc framework with C++20, more than 2000w qps in echo scene.
- title: struct_json
details: 基于反射的 json 库, 结构体和 json 的相互转换.
---

View File

@ -0,0 +1,65 @@
# struct_pb API
Current, struct_pb provide low-level APIs only, which are in namespace `struct_pb::internal`.
For example, the `SearchRequest` message from [Language Guide (proto3)](https://developers.google.com/protocol-buffers/docs/proto3#simple)
```
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
```
we generate the source code
```cpp
struct SearchRequest {
std::string query; // string, field number = 1
int32_t page_number; // int32, field number = 2
int32_t result_per_page; // int32, field number = 3
};
namespace struct_pb {
namespace internal {
// ::SearchRequest
std::size_t get_needed_size(const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
void serialize_to(char*, std::size_t, const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
bool deserialize_to(::SearchRequest&, const char*, std::size_t, ::struct_pb::UnknownFields& unknown_fields);
bool deserialize_to(::SearchRequest&, const char*, std::size_t);
} // internal
} // struct_pb
```
## Serialization
- get_needed_size
To get the buffer size, use the `get_needed_size` function.
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
an extra argument `unknown_fields` with default value is added.
- serialize_to
To serialize a message to a buffer, use the `serialize_to` function.
Before use this function, make sure the buffer is sufficiently large.
e.g. use `get_needed_size` and then allocate buffer.
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
an extra argument `unknown_fields` with default value is added.
## Deserialization
- deserialize_to
To deserialize a message from buffer, use the `deserialize_to` function.
Returns true on success.
To support [Unknown Fields](https://developers.google.com/protocol-buffers/docs/proto3#unknowns),
the overload function with an extra argument `unknown_fields` is added.

View File

@ -0,0 +1,34 @@
# Generating source code
First, you need install protobuf.
on Mac
```shell
brew install protobuf
```
on Ubuntu
```shell
apt-get install protobuf
```
on CentOS
```shell
yum install protobuf
```
Second, you need install or compile struct_pb protoc plugin `protoc-gen-struct_pb`.
Finally, you can use the following command to generate the code.
```shell
protoc --plugin=protoc-gen-struct_pb --struct_pb_out . xxx.proto
```
or use the helper function on your `CMakeLists.txt`
```cmake
find_package(Protobuf)
protobuf_generate_struct_pb(PROTO_SRCS PROTO_HDRS xxxx.proto)
```

View File

@ -0,0 +1,194 @@
# struct_pb Guide (proto3)
## Defining A Message Type
Here is a simple message type from [official document - Defining A Message Type](https://developers.google.com/protocol-buffers/docs/proto3#simple).
```
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
```
Our protoc plugin convert the message type to C++ struct and corresponding low-level serialization API.
```cpp
struct SearchRequest {
std::string query; // string, field number = 1
int32_t page_number; // int32, field number = 2
int32_t result_per_page; // int32, field number = 3
};
namespace struct_pb {
namespace internal {
// ::SearchRequest
std::size_t get_needed_size(const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
void serialize_to(char*, std::size_t, const ::SearchRequest&, const ::struct_pb::UnknownFields& unknown_fields = {});
bool deserialize_to(::SearchRequest&, const char*, std::size_t, ::struct_pb::UnknownFields& unknown_fields);
bool deserialize_to(::SearchRequest&, const char*, std::size_t);
} // internal
} // struct_pb
```
You can use the struct `SearchRequest` as a normal C++ struct.
## Enumerations
```
syntax = "proto3";
enum Corpus {
CORPUS_UNSPECIFIED = 0;
CORPUS_UNIVERSAL = 1;
CORPUS_WEB = 2;
CORPUS_IMAGES = 3;
CORPUS_LOCAL = 4;
CORPUS_NEWS = 5;
CORPUS_PRODUCTS = 6;
CORPUS_VIDEO = 7;
}
```
```cpp
enum class Corpus: int {
CORPUS_UNSPECIFIED = 0,
CORPUS_UNIVERSAL = 1,
CORPUS_WEB = 2,
CORPUS_IMAGES = 3,
CORPUS_LOCAL = 4,
CORPUS_NEWS = 5,
CORPUS_PRODUCTS = 6,
CORPUS_VIDEO = 7,
};
```
## Nested messages
Here is the sample from [proto3 Nested Types](https://developers.google.com/protocol-buffers/docs/proto3#nested)
```
syntax = "proto3";
message Outer { // Level 0
message MiddleAA { // Level 1
message Inner { // Level 2
int64 ival = 1;
bool booly = 2;
}
}
message MiddleBB { // Level 1
message Inner { // Level 2
int32 ival = 1;
bool booly = 2;
}
}
}
```
```cpp
struct Outer {
struct MiddleAA {
struct Inner {
int64_t ival; // int64, field number = 1
bool booly; // bool, field number = 2
};
};
struct MiddleBB {
struct Inner {
int32_t ival; // int32, field number = 1
bool booly; // bool, field number = 2
};
};
};
```
## Oneof
Here is the sample from [proto3 Oneof](https://developers.google.com/protocol-buffers/docs/proto3#oneof)
```
syntax = "proto3";
message SampleMessage {
oneof test_oneof {
string name = 4;
SubMessage sub_message = 9;
}
}
message SubMessage {
int32 val = 1;
}
```
The oneof type is mapped to `std::varint` with lots of helper functions.
```cpp
struct SampleMessage {
enum class TestOneofCase {
none = 0,
name = 4,
sub_message = 9,
};
TestOneofCase test_oneof_case() const {
switch (test_oneof.index()) {
case 1:
return TestOneofCase::name;
case 2:
return TestOneofCase::sub_message;
default:
return TestOneofCase::none;
}
}
std::variant<std::monostate
, std::string // string, field number = 4
, std::unique_ptr<::SubMessage> // message, field number = 9
> test_oneof;
bool has_name() const {
return test_oneof.index() == 1;
}
void set_name(std::string name) {
test_oneof.emplace<1>(std::move(name));
}
const std::string& name() const {
assert(test_oneof.index() == 1);
return std::get<1>(test_oneof);
}
bool has_sub_message() const {
return test_oneof.index() == 2;
}
void set_allocated_sub_message(::SubMessage* p) {
assert(p);
test_oneof.emplace<2>(p);
}
const std::unique_ptr<::SubMessage>& sub_message() const {
assert(test_oneof.index() == 2);
return std::get<2>(test_oneof);
}
};
struct SubMessage {
int32_t val; // int32, field number = 1
};
```
## Maps
```
syntax = "proto3";
message SampleMap {
map<string, Project> projects = 3;
}
message Project {
string name = 1;
}
```
```cpp
struct SampleMap {
std::map<std::string, ::Project> projects; // message, field number = 3
};
struct Project {
std::string name; // string, field number = 1
};
```

Some files were not shown because too many files have changed in this diff Show More