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
元數據。不要使用documentation
或repository
值填充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外部使用。