[website] refactor website and docs (#263)
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
47
gen_doc.sh
|
@ -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!'
|
|
@ -1,4 +1,4 @@
|
|||
guide
|
||||
images
|
||||
zh
|
||||
dist
|
||||
node_modules
|
||||
dist
|
||||
cache
|
||||
doxygen-awesome-css
|
||||
|
|
|
@ -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'},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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'},
|
||||
];
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
)
|
|
@ -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'},
|
||||
];
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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
|
|
@ -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`
|
||||
|
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
@ -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) |  |
|
||||
| Ubuntu 22.04 (gcc 11.2.0) |  |
|
||||
| macOS Monterey 12 (AppleClang 14.0.0.14000029) |  |
|
||||
| Windows Server 2022 (MSVC 19.33.31630.0) |  |
|
||||
|
||||
## 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.
|
|
@ -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.
|
||||
---
|
||||
---
|
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
@ -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>
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -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>
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -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>
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
@ -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="元信息头<br>(可选)" 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="完整类型信息<br>(可选)" 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="数据总长度<br>(可选)" 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="元信息头<br>(可选)" 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="完整类型信息<br>(可选)" 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="数据总长度<br>(可选)" 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>
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -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<br>(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<br>(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<br>(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<br>(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>
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
@ -251,4 +251,4 @@ class coro_rpc_client {
|
|||
*/
|
||||
auto &get_executor();
|
||||
};
|
||||
} // namespace coro_rpc
|
||||
} // namespace coro_rpc
|
|
@ -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)
|
||||
|
||||
```
|
|
@ -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)
|
|
@ -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) |  |
|
||||
| Ubuntu 22.04 (gcc 11.2.0) |  |
|
||||
| macOS Monterey 12 (AppleClang 14.0.0.14000029) |  |
|
||||
| Windows Server 2022 (MSVC 19.33.31630.0) |  |
|
||||
|
||||
## 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.
|
|
@ -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 的相互转换.
|
||||
---
|
|
@ -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.
|
|
@ -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)
|
||||
```
|
||||
|
|
@ -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
|
||||
};
|
||||
```
|