diff --git a/README.md b/README.md index b3d5840..b36bb4a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Quick Reference [Markdown](./docs/markdown.md) [MySQL](./docs/mysql.md) [Python](./docs/python.md) -[Rust](./docs/rust.md) +[Rust](./docs/rust.md) [Swift](./docs/swift.md) [SwiftUI](./docs/swiftui.md) [TOML](./docs/toml.md) @@ -90,8 +90,9 @@ Quick Reference ## Linux 命令 -[Conan](./docs/conan.md) [Awk](./docs/awk.md) +[Conan](./docs/conan.md) +[Cargo](./docs/cargo.md) [Curl](./docs/curl.md) [Chmod](./docs/chmod.md) [Cron](./docs/cron.md) diff --git a/docs/cargo.md b/docs/cargo.md new file mode 100644 index 0000000..be6e526 --- /dev/null +++ b/docs/cargo.md @@ -0,0 +1,403 @@ +Cargo 备忘清单 +=== + +此快速参考备忘清单 [Cargo](https://conan.io/) 提供了编译 [Rust](./rust.md) 常用命令和示例 + +入门 +-------- + +### 安装 Rust 和 Cargo + + +```bash +$ curl -sSf https://static.rust-lang.org/rustup.sh | sh +``` + + +在 Linux 和 macOS 系统上,这可以通过以上方命令完成 + +- [Cargo 开源仓库](https://github.com/rust-lang/cargo) _(github.com)_ +- [Cargo 官网](https://doc.rust-lang.org/cargo) _(doc.rust-lang.org)_ +- [Cargo 官网(中文)](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_ + +### 命令说明 + + +:- | :- +:- | :- +`cargo version` | 显示版本信息以确认 Cargo 已安装 +`cargo new` | 创建一个新项目 +`cargo test` | 在项目中运行单元测试 +`cargo check` | 快速编译项目,无需生成二进制文件来检查错误 +`cargo fmt` | 自动格式化代码 +`cargo build` | 编译一个项目 +`cargo run` | 一步编译和运行项目 +`cargo clippy --all-targets -- --D warnings` | Linter 检查错误 +`cargo tarpaulin --ignore-tests` | 检查代码覆盖率 + +### 创建新项目 + + +```bash +$ cargo new hello_world --bin +``` + +- `--bin` 正在制作一个二进制程序 +- `--lib` 正在创建一个库(lib) + +得到如下目录: + +```bash +$ cd hello_world +$ tree . +. +├── Cargo.toml +└── src + └── main.rs +``` + +`Cargo.toml` 被称为一个 `manifest` 元清单,它包含了 `Cargo` 编译项目所需的所有元数据 + +```toml +[package] +name = "hello_world" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +``` + +入口文件 `src/main.rs` + +```rust +fn main() { + println!("Hello, world!"); +} +``` + +运行编译生成 `hello_world` 二进制文件 + +```bash +$ cargo build +# 文件放入 `target/release` 目录 +$ cargo build --release +``` + +然后运行它: + +```bash +$ ./target/debug/hello_world +Hello, world! +``` + +也可以直接使用 `cargo run`,它会自行`编译`并`运行`它: + +```bash +$ cargo run + Running `target/hello_world` +Hello, world! +``` + +### 项目目录 + +```bash +. +├── Cargo.lock +├── Cargo.toml +├── benches # 基准目录 +│ └── large-input.rs +├── examples # 示例 +│ └── simple.rs +├── src # 源代码 +│ ├── bin +│ │ └── another_executable.rs +│ ├── lib.rs # 默认库 +│ └── main.rs # 入口文件 +└── tests # 集成测试 + └── some-integration-tests.rs +``` + +### 编译测试 + +```bash +# 编译输出二进制文件,放入 `target/debug` 目录 +$ cargo build +# 输出二进制文件,放入 `target/release` 目录 +$ cargo build --release +$ cargo run # 编译并运行 +$ cargo test # 运行您的测试 +$ cargo test foo # 传递过滤器,来运行特定测试 +``` + +### 配置目标 + + +```toml +[package] +# ... +[lib] +# 生成目标与库的名称. 本该默认是包名, 替换所有破折号为 下划线. (Rust `extern crate` 声明会参考该名;因此,该值必须是可用的有效Rust标识符) +name = "foo" +# 该字段,指向 crate 的入口(位置), 路径相对于 `Cargo.toml`. +path = "src/lib.rs" +# 一个给目标启用单元测试 的 标志. 会被 `cargo test`使用. +test = true +# 一个给目标启用文档测试 的 标志. 只与库相关, 不会影响其他部分。会被 `cargo test`使用. +doctest = true +# 一个给目标启用基准 的 标志. 会被 `cargo bench`使用. +bench = true +# 一个给目标启用文档 的 标志. 会被 `cargo doc`使用. +doc = true +# 若该目标为 编译器扩展, 那要把该字段设为 true,以让 Cargo 正确编译和,可用于所有依赖项. +plugin = false +# 若该目标为 "macros 1.1" 程序宏, 那要把该字段设为 true +proc-macro = false +# 若设为 false, `cargo test` 会为 rustc 省略 `--test` 标志, 这阻止它生成测试工具 这在二进制存在,构建管理测试运行器本身的情况下,有用. +harness = true +# 若设置了,那 目标会使用一个与`[package]`配置不同的版本, 也许是,编译一个库 2018年版本或,编译单元测试的2015年版本. 默认情况下所有目标都使用`[package]`中指定的版本进行编译。 +edition = '2015' +``` + + +### 来源配置 + +```toml +# `source` 表下,就是存储有关要更换的来源名称 +[source] + +# 在`source` 表格之下的,可为一定数量的有关来源名称. 示例下面就# 定义了一个新源, 叫 `my-awesome-source`, 其内容来自本地 # `vendor`目录 ,其相对于包含`.cargo/config`文件的目录 +[source.my-awesome-source] +directory = "vendor" + +# Git sources 也指定一个 branch/tag/rev +git = "https://example.com/path/to/repo" +# branch = "master" +# tag = "v1.0.1" +# rev = "313f44e8" + +# The crates.io 默认源 在"crates-io"名称下, 且在这里我们使用 `replace-with` 字段指明 默认源更换成"my-awesome-source"源 +[source.crates-io] +replace-with = "my-awesome-source" +``` + + +### 配置 + +```toml +# 每个源都有自己的表格,名称即是表名 +[source.the-source-name] + +# 命令 `the-source-name` 会被 `another-source`取代 +replace-with = "another-source" + +# 有几种可用的源定义(接下来有所描述) +registry = "https://example.com/path/to/index" +local-registry = "path/to/registry" +directory = "path/to/vendor" +``` + + +更换源的配置通过完成 `.cargo/config`,下面为全套可用字段是 + +包相关命令 +--- + +### init/new + + +创建一个新的 `cargo` 包 + +```bash +$ cargo init [options] [path] +$ cargo new [options] [path] +``` + +- `--bin` 创建具有二进制目标 (src/main.rs) 的包(默认行为) +- `--lib` 使用库目标 (src/lib.rs) 创建一个包 +- `--edition edition` 指定要使用的 Rust 版本。默认值为 `2021`。可能的值:2015、2018、2021 +- `--name name` 设置包名。默认为目录名称 +- `--vcs vcs` 为给定的版本控制系统(git、hg、pijul 或fossil)初始化一个新的 VCS 存储库,或者根本不初始化任何版本控制(无) +- `--registry registry` 限制仅发布到该注册表 + + +```bash +$ cargo new foo +``` + +### 安装包 + + +```bash +# 从 crates.io 安装或升级软件包: +$ cargo install ripgrep +# 在当前目录安装或重新安装包: +$ cargo install --path . +# 查看已安装包的列表: +$ cargo install --list +``` + +---- + +- `--vers version` +- `--version version` 指定要安装的版本 +- `--git url` 用于安装指定 crate 的 Git URL +- `--branch branch` 从 git 安装时要使用的分支 +- `--tag tag` 从 git 安装时使用的标记 +- `--rev sha` 从 git 安装时使用的特定提交 +- `--path path` 要安装的本地 crate 的文件系统路径 +- `--list` 列出所有已安装的软件包及其版本 +- `-f`, `--force` 强制覆盖现有的 crate 或二进制文件 + +### 搜索包 + +```bash +$ cargo search [options] [query...] +``` + +- `--limit limit` 限制结果数量(默认值:10,最大值:100) +- `--index index` 要使用的注册表索引的 URL +- `--registry registry` 要使用的注册表的名称 + +```bash +$ cargo search serde +``` + +### 卸载包 + +```bash +$ cargo uninstall [options] [spec...] +``` + +- `-p`, `--package spec...` 要卸载的软件包 +- `--bin name...` 仅卸载二进制名称 +- `--root dir` 从中卸载软件包的目录 + +```bash +$ cargo uninstall ripgrep +``` + +发布命令 +--- + +### 登录 + +```bash +$ cargo login [options] [token] +``` + +---- + +:-|:- +:-|:- +`--registry` | 要使用的注册表的名称 + +---- + +:-|:- +:-|:- +`-v`, `--verbose` | 启用更加详细的输出 +`-q`, `--quiet` | 不输出Cargo的日志信息 +`--color when` | 输出内容的颜色 `auto`, `always`, `never` + +### 所有者 + +```bash +# 列出包的所有者: +$ cargo owner --list foo +# 邀请所有者加入包: +$ cargo owner --add username foo +# 从包中删除所有者: +$ cargo owner --remove username foo +``` +---- + +:-|:- +:-|:- +`--token token` | 身份验证时使用的 API 令牌 +`--index index` | 要使用的注册表索引的 URL + +### 打包 & 发布公共选项 + + +选择包 + +- `-p spec...`, `--package spec...` Package 指定包 +- `--workspace` Package 工作区中的全体成员 +- `--exclude SPEC...` 排除指定包 + +编译选项 + +- `--target triple` 为指定架构执行 Package +- `--target-dir directory` 用于存放生成的工件以及中间文件的目录 + +特性选择 + +- `--features features` 传递以空格或者逗号分隔的列表,其中给出要启用的特性 +- `--all-features` 为给定的包启用全部可用特性 +- `--no-default-features` 不启用给定包的default特性 + +清单选项 + +- `--manifest-path path` 用于指定 Cargo.toml 文件的路径 +- `--frozen`, `--locked` 这两个选项用于保证Cargo.lock文件是最新的 +- `--offline` 禁止Cargo访问网络 + +混杂选项 + +- `-j N`, `--jobs N` 要并行运行的作业数量 + +### 打包 + +将本地包打包为可分发的压缩文件 + +```bash +$ cargo package [options] +``` + +---- + +- `-l`, `--list` 输出包中包含的文件(不实际进行打包)。 +- `--no-verify` 构建包时不进行校验。 +- `--no-metadata` 忽略 缺少可读的元信息(如描述信息或采用的授权协议) 时产生的警告。 +- `--allow-dirty` 允许打包 在版本控制系统中仍有未提交内容 的包。 + +### 发布 + + +```bash +$ cargo publish [options] +``` + +发布选项 + +- `--dry-run` 在不上传的情况下执行所有检查 +- `--token token` 身份验证时使用的 API 令牌 +- `--no-verify` 不要通过构建内容来验证内容 +- `--allow-dirty` 允许打包具有未提交的 VCS 更改的工作目录 +- `--index index` 要使用的注册表索引的 URL +- `--registry registry` 要发布到的注册表的名称 + +打包选择 + +- `-p spec`, `--package spec` 要发布的包 + +### yank + +从服务器的索引中删除以前发布的 crate 版本 + +```bash +$ cargo yank --vers 1.0.7 foo +``` + +- `--vers version` 要 yank 或 un-yank 的版本 +- `--undo` 撤消 yank,将版本放回索引中 +- `--token token` 身份验证时使用的 API 令牌 +- `--index index` 要使用的注册表索引的 URL +- `--registry registry` 要使用的注册表名称 + +另见 +--- + +- [The Cargo Book](https://doc.rust-lang.org/stable/cargo/) _(doc.rust-lang.org)_ +- [Cargo 手册 中文版](https://www.rustwiki.org.cn/zh-CN/cargo/index.html) _(rustwiki.org.cn)_ \ No newline at end of file diff --git a/docs/rust.md b/docs/rust.md index f29879e..c48cd53 100644 --- a/docs/rust.md +++ b/docs/rust.md @@ -35,10 +35,10 @@ Hello, World! 查看: [Rust 类型](#rust-类型) -### Formatting +### 格式化 -```rust {.wrap} +```rust // 单个占位符 println!("{}", 1); // 多个占位符 @@ -108,9 +108,70 @@ fn main(){ 查看: [Functions](#rust-函数) +### 声明宏 + +```rust +macro_rules! foo { + ($l:tt) => { bar!($l); } +} +macro_rules! bar { + (3) => {} +} +foo!(3); +``` + +### 元变量 + + +:- | :- +:- | :- +`item` | 程序项 +`block` | 块表达式 +`stmt` | 语句
_(注意此选择器不匹配句尾的分号)_ +`pat` | 模式 +`expr` | 表达式 +`ty` | 类型 +`ident` | 标识符或关键字 +`path` | 类型表达式 形式的路径 +`tt` | `token` 树
_(单个 `token` 或宏匹配定界符 `()`、`[]` 或 `{}` 中的标记)_ +`meta` | 属性,属性中的内容 +`lifetime` | 生存期 `token` +`vis` | 可能为空的可见性限定符 +`literal` | 匹配 `-?` 字面量表达式 + +### 结构体 + +```rust +struct Point { x: i32, y: i32 } +let p = Point { x: 10, y: 11 }; +let px: i32 = p.x; +``` + +结构体是一个使用关键字 `struct` 定义的标称型(nominal)结构体类型 + +### 枚举 + +```rust +enum Foo { + Bar, // 0 + Baz = 123, // 123 + Quux, // 124 +} + +let baz_discriminant = Foo::Baz as u32; +assert_eq!(baz_discriminant, 123); +``` + Rust 类型 -------- +### 类型别名 + +```rust +type Point = (u8, u8); +let p: Point = (41, 68); +``` + ### 整数 ```rust @@ -148,7 +209,7 @@ let emoji = "\u{1f600}"; // => 😀 ### 字符串字面量 -```rust {.wrap} +```rust let community_name = "AXIAL"; let no_of_members: &str = "ten"; println!("社区的名称是 {community_name},它有 {no_of_members} 个成员"); @@ -663,6 +724,16 @@ fn multiply (mut arr: [i32 ; 5]) -> [i32 ; 5]{ ``` +### 泛型函数 + +```rust +use std::fmt::Debug; +fn foo(x: &[T]) where T: Debug { + // 省略细节 +} +foo(&[1, 2]); +``` + 杂项 ----- @@ -724,6 +795,7 @@ println!("{a_number}"); 另见 -------- +- [Cargo 备忘清单](./cargo.md) _(jaywcjlove.github.io)_ - [The Rust Document](https://doc.rust-lang.org/book/ch00-00-introduction.html) _(doc.rust-lang.org)_ - [The Rust Reference](https://doc.rust-lang.org/reference/introduction.html) _(doc.rust-lang.org)_ - [Rust Cheatsheet](https://phaiax.github.io/rust-cheatsheet/) _(phaiax.github.io)_ diff --git a/scripts/assets/cargo.svg b/scripts/assets/cargo.svg new file mode 100644 index 0000000..3956ac0 --- /dev/null +++ b/scripts/assets/cargo.svg @@ -0,0 +1,3 @@ + + + diff --git a/scripts/utils/homeCardIcons.mjs b/scripts/utils/homeCardIcons.mjs index f78521e..bc8d221 100644 --- a/scripts/utils/homeCardIcons.mjs +++ b/scripts/utils/homeCardIcons.mjs @@ -3,13 +3,23 @@ import path from 'path'; import { getSVGNode, ICONS_PATH } from './getSVGNode.mjs'; export function homeCardIcons(node, parent, isHome) { - if (isHome && node && node.type === 'element' && node.properties?.class?.includes('contributing')) { + if ( + isHome && + node && + node.type === 'element' && + (node.properties?.class || node.properties?.className)?.includes('contributing') + ) { const info = node.properties['data-info']; if (!info) { node.properties['data-info'] = '👆待完善需要您的参与'; } } - if (isHome && node && node.type === 'element' && node.properties?.class?.includes('home-card')) { + if ( + isHome && + node && + node.type === 'element' && + (node.properties?.class || node.properties?.className)?.includes('home-card') + ) { node.children = node.children.map((child) => { const href = child.properties?.href; if (href) {