docs: 开源规范化 — doc comments + 社区文件 + 示例代码 + crates.io 就绪

- 为 core 公开 API 添加完整 doc comments(rustdoc 可用)
- 新增 .editorconfig / CONTRIBUTING / CODE_OF_CONDUCT / SECURITY
- 新增 Issue 模板(bug + feature)+ PR 模板
- 新增 3 个代码示例(examples/)
- 更新 Cargo.toml 元数据(description/repository/keywords/categories/MSRV)
- 更新 README + CHANGELOG
This commit is contained in:
2026-06-19 18:56:28 +08:00
parent cbcd4e5123
commit ce8063431e
17 changed files with 640 additions and 18 deletions
+73 -8
View File
@@ -1,17 +1,33 @@
use serde::Serialize;
use std::sync::OnceLock;
/// 纠错级别
/// QR 码纠错级别
///
/// 决定 QR 码被遮挡/损毁后仍可扫描的能力。纠错越强,可存储的数据越少。
///
/// ```rust
/// use qr_core::version::{EcLevel, Version};
///
/// let ver = Version::new(1).unwrap();
/// let h = ver.ec_info(EcLevel::H);
/// let l = ver.ec_info(EcLevel::L);
/// // H 级纠错码字更多,数据码字更少
/// assert!(h.ec_per_block > l.ec_per_block);
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum EcLevel {
L, // 约 7%
M, // 约 15%
Q, //25%
H, // 约 30%
/// L 级 — 约 7% 纠错能力
L,
/// M 级 —15% 纠错能力(默认)
M,
/// Q 级 — 约 25% 纠错能力
Q,
/// H 级 — 约 30% 纠错能力
H,
}
impl EcLevel {
/// 格式信息中使用的指示位
/// 格式信息中使用的 2-bit 指示位
pub fn indicator_bits(self) -> u8 {
match self {
EcLevel::L => 0b01,
@@ -22,7 +38,23 @@ impl EcLevel {
}
}
/// 版本号 1~40
/// QR 码版本号1~40
///
/// 版本决定 QR 码的物理尺寸:`side = 17 + version × 4` 模块。
/// 版本 1 是 21×21,版本 40 是 177×177。
///
/// ```rust
/// use qr_core::version::Version;
///
/// let v1 = Version::new(1).unwrap();
/// assert_eq!(v1.size(), 21);
///
/// let v40 = Version::new(40).unwrap();
/// assert_eq!(v40.size(), 177);
///
/// assert!(Version::new(0).is_none());
/// assert!(Version::new(41).is_none());
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub struct Version(pub u8);
@@ -104,16 +136,27 @@ impl Version {
}
}
/// 纠错分组信息
///
/// 一组 QR 数据被分为多个块,每个块独立计算 RS 纠错码。
#[derive(Debug, Clone)]
pub struct EcInfo {
/// 数据码字总数
pub total_codewords: u16,
/// 每个块的纠错码字数
pub ec_per_block: u8,
/// 分组信息(1~2 组,不同数据码字数)
pub blocks: Vec<BlockInfo>,
}
/// 单个分组信息
///
/// 所有块的数据码字总数 + 纠错码字总数 = QR 码总容量。
#[derive(Debug, Clone)]
pub struct BlockInfo {
/// 该组块数
pub count: u16,
/// 每个块的数据码字数
pub data_codewords: u16,
}
@@ -1290,6 +1333,16 @@ fn init_capacity_table() -> [[u16; 4]; 40] {
table
}
/// 查询指定版本+纠错级别的数据码字容量
///
/// 返回数据码字数(非比特数),乘以 8 得比特容量。
///
/// ```rust
/// use qr_core::version::{get_data_capacity, Version, EcLevel};
///
/// let cap = get_data_capacity(Version(1), EcLevel::M);
/// assert_eq!(cap, 16); // 版本 1-M 有 16 个数据码字
/// ```
// SAFETY: version.0 ∈ [1,40] 由 Version::new() 保证; level 是 4 变体枚举
#[allow(clippy::indexing_slicing)]
pub fn get_data_capacity(version: Version, level: EcLevel) -> u16 {
@@ -1298,7 +1351,19 @@ pub fn get_data_capacity(version: Version, level: EcLevel) -> u16 {
cap[version.0 as usize - 1][level as usize]
}
/// 自动选择最小版本:返回能容纳 data_bits 比特的最小版本
/// 自动选择能容纳 `data_bits` 比特的最小版本
///
/// 返回 `None` 表示数据量超出 QR 码最大容量(版本 40)。
///
/// ```rust
/// use qr_core::version::{pick_version, EcLevel};
///
/// let v = pick_version(100, EcLevel::M).unwrap();
/// assert_eq!(v.0, 1); // 版本 1-M 可容纳 16×8=128 bit >= 100
///
/// let too_big = pick_version(50_000, EcLevel::H);
/// assert!(too_big.is_none());
/// ```
pub fn pick_version(data_bits: u16, level: EcLevel) -> Option<Version> {
for v in 1..=40 {
let cap_bits = get_data_capacity(Version(v), level) * 8;