Rustでライブラリを作成するためのヒント

Pascal Hertleifの記事「Rustライブラリを作成するためのグッドプラクティス」 (2015.10.24)。









約1年後、Mozilla Researchのプログラミング言語であるRustに興味を持ち、セキュリティ、速度、並行性の3つのタスクに焦点を当てました。 CやC ++と同程度の低レベルで、優れた型システム(ジェネリックと特性を備えた)、使いやすいコンパイラー、優れたCargoパッケージマネージャーを備えています。







Rust 1.0リリース (2015年5月)から6か月が経過しました 。私の一部を含む多くのライブラリ(パッケージ、クレート)がcrates.ioの中央レジスタに公開されました。 他の人があなたのライブラリを見つけ、使用し、補完するのに役立ついくつかの優れたプラクティスを紹介します(「ベスト」と呼ぶには早すぎます)。









コードをきれいに保つ



もちろん、最も重要なことはコード自体です。 Rustはデフォルトで多くのことをチェックしますが、コードを改善するためにできることは他にもあります。







この記事では、コードを記述するための具体的なヒントについては説明しません。 ただし、ライブラリのロジックやアーキテクチャパターンの構造化に関するヒントに興味がある場合は、いつでも公式の本翻訳 )とRust Design Patternsを参照できます。









rustfmt



rustfmtは自動的にコードを再フォーマットし、特に著者以外の人(車はカウントしません-コンパイルするとコードを理解します)に理解しやすくします(翻訳者の注意:スタイルに関する無駄な引数も停止します)。 そして、彼はこれについてはかなり良い仕事をしている。まあ、少なくとも彼は私のコードで何も台無しにしていない。 このコマンドを時々実行するだけです(翻訳者のメモ:または.rs



拡張子でファイルを保存するときに自動rustfmtをエディターに追加してください)。これにより、コードは残りのRustコードのようになります。







 $ rustfmt src/lib.rs
      
      





One True Rustスタイルを定義する試みが行われているにもかかわらず、rustfmtはデフォルトでそれに従うことを試みますが、 ここでフォーマットオプションのリストを見つけることができます。 現時点では、私のプロジェクトのほとんどは次の設定を使用しています(これをプロジェクトのルートにあるrustfmt.tomlファイルに保存します):







 format_strings = false reorder_imports = true
      
      





(翻訳者のメモ:ところで、 cargo install rustfmt



を介してcargo install rustfmt



cargo fmt



サブコマンドが利用可能になりました。しかし個人的には、rusfmt形式は腹立たしく、オプションを最後まで修正するのに役立たなかったため、実装を延期しました。)









より多くのチェックを使用します。



チェック(リント)は、ビルド時にコードをチェックする小さなコンパイラプラグインです(主にスタイルエラーについて)。 デフォルトでは、rustcにはすでにdead-code



デッドコードの警告)やnon-snake-case



(一部の要素の名前がsnake_caseにないnon-snake-case



警告)などの警告がすでに含まれています。







他にも非常に便利な組み込みチェックがいくつかあります。 #![warn(...)]



#![deny(...)]



置き換えることにより、それらを本格的なアセンブリエラーに変えることもできます( マニュアルを参照)。 通常、これらをプロジェクトに追加します。







 #![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts, trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces, unused_qualifications)]
      
      





最初のmissing_docs



は特に便利です。コードに文書化されていないパブリックインターフェイスがある場合に起動します。 unsafe_code



も非常に便利です。そのおかげで、ライブラリは人々の目にはより信頼できるように見えます。







使用可能なすべてのチェックとその説明のリストは、 rustc -W help



コマンドの出力にあります。









神のチェックへのさらなるチェック!



リントが良いことにすでに気付いていると思います。 したがって、 clippyの作者はさらに100を書きました(実際、バージョン0.0.21については約68です(翻訳者のメモ: すでにもっと ))。 clippyは今のところコンパイラプラグインであるため、それを操作するにはrutscの夜間アセンブリが必要になります。これはさまざまな方法で呼び出すことができます。たとえば、 cargo-clippyを使用するか、プロジェクトのオプションの依存関係として追加します。







私は最後のオプションを好むので、これを私のCargo.tomlに追加しました:







 [dependencies] clippy = {version = "0.0.21", optional = true} [features] default = [] dev = ["clippy"]
      
      





これらの設定により、clippyはオプションの依存関係となり、 dev



フラグが設定されている場合にのみ有効になります。 メインパッケージファイルには、オプションで次のように含めることができます。







 #![cfg_attr(feature = "dev", allow(unstable_features))] #![cfg_attr(feature = "dev", feature(plugin))] #![cfg_attr(feature = "dev", plugin(clippy))]
      
      





cargo build --features "dev"



してプロジェクトをcargo build --features "dev"



と、自動的にクリップチェックがトリガーされます。 (もちろん、以前に禁止していた場合にのみ、 unstable_features



を許可する必要があります)。







警告:現在、コンパイラプラグインは不安定です。 新しいコンパイラナイトアセンブリをアップグレードすると、clippyが破損する可能性があります。 クリップの作成者は通常、すべてをすばやく修正します。







(翻訳者のメモ: clippyオンラインバージョンは比較的最近登場しましたが、今では夜のrustcのローカルインストールに煩わされず、Readme.mdにもう1つバッジを付ける理由があります!)







組み込みのチェックと同様に、clippyの一部のチェックはデフォルトでオフになっています。 完全なリストを見つけるためにクリップドキュメンテーションを見て、あなたのために面白いものを含めてください!









テスト



Rustには素晴らしいテストサポートが組み込まれています。モジュールのテストをモジュール内ですばやく記述できます。また、cargoが自動的に実行します( tests/



ディレクトリ内の*.rs



ファイル)。 ああ、 ドキュメント内のexamples/



(またはexamples/



)もテストされます。







ここで言うことはこれ以上ありません。 公式の本の章を読んでください( 翻訳 )。









プロジェクトのインフラ



コード自体に加えて、プロジェクトを公開するときに考慮する必要がある他のポイントがあります。 これらは主にGitHubでコードを公開する人に役立ちますが、これらのヒントの一部はそれなしで適用されます。









貨物メタデータ



便利なライブラリの検索を容易にするための最初の(そして最も簡単な)ことは、 Cargo.toml



ファイルにCargo.toml



です。 crates.ioには多くのメタデータフィールドがあります。 HSLパッケージの例を次に示します。







 [package] name = "hsl" version = "0.1.0" authors = ["Pascal Hertleif <my@email.address>"] repository = "https://github.com/killercup/hsl-rs.git" homepage = "https://github.com/killercup/hsl-rs.git" license = "MIT" readme = "README.md" documentation = "http://killercup.github.io/hsl-rs/" description = "Represent colors in HSL and convert between HSL and RGB."
      
      





ところで、依存関係に'*'



バージョンを使用しないでください-crates.ioは 、Cargoが依存するセマンティックバージョニングを無視するため、そのようなパッケージ拒否します。 また、依存するパッケージの最新バージョンの追加を簡素化するために、 cargo-editを使用できます









README.md



リポジトリの開始ページを見ている人は、 Readme.md



ファイルの内容を見る可能性が高くなります。 標準的な質問に対する回答があることを確認してください。









(翻訳者注:ところで、ライセンスについて:1月に、Rustコミュニティは重要なプロジェクトのほとんどをデュアルMIT / Apache-2.0ライセンスに移行し、デフォルトで将来使用することを勧めています。引数は、たとえばcgmathライブラリタスクにあります 。)







また、 Readme.md



、ライブラリの小さな使用例を投稿するのに最適な場所です。多くの場合、人々がライブラリを理解し始めるのに便利です。 Readme.md



(およびMarkdown形式の他のドキュメント)の例が動作することを確認するには、 skepticを使用できます。 Cargoアセンブリプロセス( build.rs



ファイル)に小さなフックを追加することで、懐疑的な人を呼び出して、Markdownファイルのコードサンプルを通常のテストに変換できます。 (詳細については、懐疑的なドキュメントを参照してください。)









その他のメタファイル



.gitignore



ファイルを追加することを忘れないでください。ここでは、gitがtarget/



ディレクトリを追跡することは禁止されています( .gitignore



注意:Cargoは一時ファイルとアセンブリアーティファクトにこのディレクトリを使用するため、 ハード通貨で修正する意味はありません)。 ライブラリパッケージ(つまり、実行可能ファイルを生成しない)の場合、 Cargo.lock



ファイルも無視するCargo.lock



ます(翻訳者のメモ: why )。







すべてのプロジェクトに追加しようとしている別のファイルは.editorconfig



です。 次の設定を使用します。







 root = true [*] end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true indent_style = space indent_size = 4 [*.md] trim_trailing_whitespace = false
      
      







継続的インテグレーション



オープンソースプロジェクトがGitHubでホストされている場合、 Travis CIの継続的統合サービスを無料で使用できます。 提出された変更(コミット)または追加要求ごとに、さまざまな環境(たとえば、Rustの安定版、ベータ版、夜間バージョン、または異なるアーキテクチャ)でテストの自動起動を構成できるため、便利です。







travis-cargoを使用すると、Travisでテストとベンチマークを実行し、ドキュメントを生成(およびGitHub Pagesにプッシュ)、テストカバレッジを読み取り(およびCoverallsに送信)できます。







この.travis.yml



テンプレートのようなものを使用します。







 sudo: false language: rust rust: - nightly - beta - stable matrix: allow_failures: - rust: nightly before_script: - | pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - | travis-cargo build && travis-cargo test && travis-cargo bench && travis-cargo --only stable doc addons: apt: packages: - libcurl4-openssl-dev - libelf-dev - libdw-dev after_success: - travis-cargo --only stable doc-upload - travis-cargo coveralls --no-sudo notifications: email: on_success: never env: global: - TRAVIS_CARGO_NIGHTLY_FEATURE=dev - secure: #   
      
      





(翻訳者のメモ:オリジナルでは、これは「基本設定」と呼ばれますが、「基本」は単にsudo: false\nlanguage: rust



であるため、ここでは同意しません)







この構成には、特にclippyを起動するためのいくつかのオプションがあります。夜間コンパイラによるビルド結果は重要ではありません(プラグインインターフェイスは変更でき、すべてが壊れます)。夜間コンパイラはdev



フラグで呼び出されます。







TravisはLinuxおよびMac OS Xでビルドできます。Windowsでのテストについては、 AppVeyorをご覧ください (オープンソースプロジェクトでも無料です)。 (翻訳者のメモ:非常に便利ですが、Travisサービスに比べて非常に遅いです。)









ドキュメントの自動生成



travis-cargoでサポートされている生成されたドキュメントの自動読み込み(つまり、rust-doc出力をgh-pagesブランチに送信(プッシュ)する)を有効にするには、アカウントのアクセストークンを含むGH_TOKEN



環境変数を追加する必要がありますGitHub(制限付き権利)。 ここで作成できます(各プロジェクトに1つあります)。 マーカーを暗号化するには、プロジェクトのルートディレクトリで実行してTravisCLIユーティリティ( gem install travis



travisと共にgem install travis



)を使用できます( 1234



をマーカーに置き換えます)。







 $ travis encrypt "GH_TOKEN=1234" --add env.global
      
      





すべてが正しく構成されたら、 .github.io/



プロジェクト文書(例: killercup.github.io/hsl-rs)が表示されます。







(翻訳者のメモ:htmlでレンダリングされたドキュメントをプロジェクトブランチにプッシュすることは非常に一般的な慣行ですが、アイデアのように思えます。理想的には、crates.ioはrustdocをプルし、その出力を保存/表示する( godoc.orgの精神で。crates.fyiの形で良い松葉杖がありますが 。)









ほむ



継続的インテグレーションを使用すると、プルリクエストのコードが機能し、マージの準備ができていることを確認できます。 githubの最新の変更- 必須チェック(ステータスチェック)translation )で保護されたブランチにより 、マージの前にすべてのテストに合格したことを確認できます。 しかし、ブランチとマスターの注入後にテストが合格するかどうかはわかりません!







GitHubのRustプロジェクトは、 Bors統合ロボットを使用してこの問題を解決します。包含リクエスト自体をマージする代わりに、Borsにこれを行うように指示します。 Borsは、1つの要求を含め(キューがあります)、それを現在のマスターにマージし、すべてのテストを実行し、成功した場合、マスターブランチに新しいバージョンを送信します。 これは、多数のインクルード要求の影響に時間がかかる可能性があることを意味しますが、すべてのテストが常にウィザードで実行されるので安心できます。







Borsaコアはhomuと呼ばれ、プロジェクトで使用できます。 githubでhomuをコラボレーターとして追加し、 homu.ioでプロジェクトを登録し、コメント@homu r+



を使用して包含リクエストをマージします。









その他のトリック



もっと知りたいですか? OK、ここにいくつかのヒントがあります:









(翻訳者のメモ:私はClogの使用については本当に同意しません。 ここで 、私にとって、優れた変更ログは、これは自動的に機能しません。しかし、おそらく、自動変更ログはまったくないよりはましです。)









おわりに



最後まで読んでくれてありがとう! 次のライブラリ(Rust)でここで説明されている手法のいくつかを使用してください。








All Articles