【譯文】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閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容