美文网首页Rust探索
【译文】Rust API 指南:如何写文档

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

作者: 袁承兴 | 来源:发表于2020-12-09 20:03 被阅读0次

    原文: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外部使用。

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/xehkgktx.html