【译文】Rust API 指南:如何写文档

原文:Rust API Guidelines chapter 4

Crate级别的文档应非常详尽,并包含示例(C-CRATE-DOC)

RFC1687.

所有条目都应有一个rustdoc示例(C-EXAMPLE)

每个公共模块,特型,结构,枚举,函数,方法,宏和类型定义都应具有一个示例,用于该功能的练习。

该准则应在合理范围内适用。

有时,附上另一个条目的适用示例的链接可能就足够了。例如,如果恰好一个函数使用特定类型,则可以在该函数或类型上编写单个示例后,从另一个链接到该示例。

示例的目的并不总是显示如何使用该条目。虽然读者希望了解如何调用函数,在枚举上进行匹配,以及一些基本任务。但是,一个示例最应该表明为什么要使用这个条目。

// 这是使用clone()的不良示例。它机械地显示*如何*
// 调用clone(),但没有显示出*为什么*要这样做。
fn main() {
    let hello = "hello";
​
    hello.clone();
}

示例使用?,不是try !,也不是unwrap(C-QUESTION-MARK)

不管喜欢与否,用户通常逐字复制示例代码。Unwrapping an error应该是用户需要做出的决定。

下面是这种常见的方式会构建易出错的示例代码。以#开头的行是在构建示例时通过cargo test编译的,但不会出现在用户可见的rustdoc中。

/// ```rust
/// # use std::error::Error;
/// #
/// # fn main() -> Result<(), Box<dyn Error>> {
/// your;
/// example?;
/// code;
/// #
/// #     Ok(())
/// # }
///

函数文档应包括错误,恐慌和安全注意事项(C-FAILURE)

错误条件应记录在“错误”部分中。这也适用于trait方法--实现允许或预期返回错误的trait方法应在“错误”部分进行记录。

例如在标准库中,std::io::Read::read trait方法的某些实现可能返回错误。

/// 从该源提取一些字节到指定的缓冲区中,返回
/// 读取了多少字节。
///
/// ... lots more info ...
///
/// # Errors
///
/// 如果此函数遇到任何形式的I/O或其他错误,错误
/// 变体将返回。如果返回错误,则必须
/// 保证不会读取任何字节。

恐慌情况应记录在“恐慌情况”部分。这也适用于trait方法-实现允许或预期产生恐慌的traits方法应在“ Panics”部分记录。

在标准库中,Vec::insert方法可能会出现恐慌。

/// 在向量中的索引位置处插入一个元素,将
/// 它后面的所有元素向右移位。
///
/// # Panics
///
/// 如果`index`超出范围,则产生恐慌。

不必记录所有可能的恐慌情况,特别是如果恐慌情况发生在调用方提供的逻辑中。例如,在以下代码中记录Display恐慌似乎过多。但如果不确定,也不是记录更多恐慌情况就更好。

/// # Panics
///
/// This function panics if `T`'s implementation of `Display` panics.
pub fn print<T: Display>(t: T) {
    println!("{}", t.to_string());
}

不安全的函数应记录在“安全性”部分,该部分说明了由调用者负责维护正确使用该函数的所有不变量。

不安全的std::ptr::read需要以下调用者。

/// 从`src`中读取值而不移动它。这使得
/// `src`中的内存不变。
///
/// # 安全
///
/// 除了接受原始指针之外,这是不安全的,因为它在语义上
/// 将值移出src,而不阻止未来使用src。
/// 如果`T`不是`Copy`,则必须注意确保`src`的值被
/// 数据再次覆盖之前不会使用(例如,使用`write`,
/// `zero_memory`或`copy_memory`)。注意,`*src = foo`也算使用
/// ,因为它将尝试把先前的值放在`*src`处。
///
/// 指针必须对齐;如果不是这种情况,请使用`read_unaligned`。

包含指向相关内容的超链接(C-LINK)

链接到相同类型内的方法通常如下所示:

[`serialize_struct`]: #method.serialize_struct

指向其他类型的链接通常如下所示

[`Deserialize`]: trait.Deserialize.html

链接也可能指向父模块或子模块:

[`Value`]: ../enum.Value.html
[`DeserializeOwned`]: de/trait.DeserializeOwned.html

RFC 1574在"Link all the things"标题下正式建议该准则。

Cargo.toml包含所有常见的元数据(C-METADATA)

Cargo.toml的[package]部分应包含以下值:

  • authors
  • description
  • license
  • repository
  • readme
  • keywords
  • categories

此外,还有两个可选的元数据字段:

  • documentation
  • homepage

默认情况下,http://crates.io会把crate的文档链接到docs.rs上。仅当文档托管在docs.rs以外的其他位置时,才需要设置documentation元数据,例如,因为crate链接到了docs.rs构建环境中不可用的共享库。

仅在有唯一的网站而不是代码库或API文档的情况下设置homepage元数据。不要使用documentationrepository值填充homepage。比如,serde将homepage设置为专用网站https://serde.rs

Crate设置html_root_url属性(C-HTML-ROOT)

假设crate使用docs.rs作为其主要API文档,则它应指向"https://docs.rs/CRATE/MAJOR.MINOR.PATCH"

html_root_url属性告诉rustdoc在编译下游crates时如何为crate中的项目创建URL。没有它,依赖于您的crate的crate文档中的链接将不正确。

#![doc(html_root_url = "https://docs.rs/log/0.3.8")]

由于此URL包含确切的版本号,因此必须与Cargo.toml中的版本号保持同步。 [version-sync](https://link.zhihu.com/?target=https%3A//crates.io/crates/version-sync)的crate可以帮助您解决此问题,方法是让您添加一个集成测试,如果html_root_url版本号与crate版本不同步,则该集成测试将失败。

如果您不喜欢这种机制,建议在Cargo.toml版本密钥中添加一条注释,提醒您自己将两者保持更新,例如:

version = "0.3.8" # remember to update html_root_url

对于在docs.rs外部托管的文档,如果在crate名称+ index.html后面的附加带您到crete根模块的文档,则html_root_url的值正确。例如,如果根模块的文档位于"https://api.rocket.rs/rocket/index.html",则html_root_url将为"https://api.rocket.rs"

Release notes记录所有重大更改(C-RELNOTES)

crate的用户可以阅读release notes,以找到crate每个已发行版本中发生更改的摘要。crate级文档和/或Cargo.toml中链接的存储库中应包含release notes的链接或说明本身。

release notes中应明确标识重大更改(如RFC 1105中所定义)。

如果使用Git跟踪crate的源代码,则发布到http://crates.io的每个发行版都应具有一个相应的tag,用于标识已发布的提交。非Git VCS工具也应使用类似的过程。

# Tag the current commit
GIT_COMMITTER_DATE=$(git log -n1 --pretty=%aD) git tag -a -m "Release 0.3.0" 0.3.0
git push --tags

首选带注释的标签,因为如果存在任何带注释的标签,则某些Git命令会忽略未注释的标签。

Example

Rustdoc不要显示无用的实现细节(C-HIDDEN)

Rustdoc应该包括用户完全使用crate所需的一切。可以在技术文章中解释相关的实现细节,但是它们不应该是文档中的真实条目。

尤其要选择在rustdoc可以看到哪些实现--所有用户需要使得能完全使用crate。在以下代码中,默认情况下,PublicError的rustdoc将显示From <PrivateError> impl。我们选择使用#[doc(hidden)]隐藏它,因为用户的代码中永远不会出现PrivateError,因此该隐含内容永远与他们无关。

// This error type is returned to users.
pub struct PublicError { /* ... */ }
​
// This error type is returned by some private helper functions.
struct PrivateError { /* ... */ }
​
// Enable use of `?` operator.
#[doc(hidden)]
impl From<PrivateError> for PublicError {
    fn from(err: PrivateError) -> PublicError {
        /* ... */
    }
}

[pub(crate)](https://link.zhihu.com/?target=https%3A//github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md) 是另一个用于从公共API删除实现细节的好工具。它允许项目从其自身模块的外部使用,但不能在同一crate外部使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容