Skip to content

Commit bdb8281

Browse files
authored
Merge pull request #735 from lsst-dm/u/ktl/tweak-rust
Minor fixes.
2 parents 4059023 + f077f3a commit bdb8281

1 file changed

Lines changed: 43 additions & 43 deletions

File tree

rust/rust.rst

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,38 @@ LSST Rust Development Guide
77
This guide details the standards and best practices for writing Rust code within the LSST DM Stack and includes basic knowledge of the package.
88
Rust is being adopted to provide performance-critical components and leverage its memory safety features.
99
Of note, we are making use of Rust's memory safety in the sense of the design of the language.
10-
This does not mean one can not use unsafe blocks where appropriate, but they should be used with due consideration and held to the same standards as where they are used elsewhere in rust.
11-
For sexample, unsafe blocks should be liminted in scope to the smallest size needed to accomplish a unit of work.
10+
This does not mean one can not use unsafe blocks where appropriate, but they should be used with due consideration and held to the same standards as where they are used elsewhere in Rust.
11+
For example, unsafe blocks should be limited in scope to the smallest size needed to accomplish a unit of work.
1212

13-
There should be careful consideration when writing new code in rust.
14-
The line between when something is simple enough and should be done in python with a small performance hit, vs written in rust and bound to python is a hard line to define and is left up to our 'empowering developers' directive for them to make the most informed decision.
13+
There should be careful consideration when deciding to write new code in Rust.
14+
The line between when something is simple enough and should be done in Python with a small performance hit versus written in Rust and bound to Python is hard to define and is left up to our 'empowering developers' directive for them to make the most informed decision.
1515
This document assumes a basic understanding of Rust and the LSST DM Stack.
1616

17-
The de-facto location, and reference implementation, of rust within the lsst science pipelines is in a package called ``rubinoxide``.
18-
This does not mean developers are not allowed to use rust in another dedicated package, but unless there is a compelling reason to do so rust code should be placed in ``rubinoxide``.
19-
This guide assumes the package layout of ``rubinoxide``.
17+
The *de facto* location, and reference implementation, of Rust within the LSST Science Pipelines is in a package called ``rubinoxide``.
18+
This does not mean developers are not allowed to use Rust in another dedicated package, but unless there is a compelling reason to do so Rust code should be placed in ``rubinoxide``.
19+
This guide defines the package layout of ``rubinoxide``.
2020
Any other Rust based packages that are written should adhere to this as best as possible.
2121

2222
2. Rust Version
2323
---------------
2424

25-
All LSST Rust code must be compatible with the standard Rust toolchain provided in the rubin-env conda environment.
25+
All LSST Rust code must be compatible with the standard Rust toolchain provided in the ``rubin-env`` conda environment.
2626

2727
3. Resources
2828
------------
2929

30-
Unlike the c++ section of the guide, where the language has no clear community consensus or resources, we defer to standard published rust resources guidance on how to work with rust.
30+
Unlike the C++ section of the guide, where the language has no clear community consensus or resources, we defer to standard published Rust resources for guidance on how to work with Rust.
3131

32-
* The `Rust Book <https://doc.rust-lang.org/book/>`_ is a good resource to find out information on the rust language.
32+
* The `Rust Book <https://doc.rust-lang.org/book/>`_ is a good resource to find out information on the Rust language.
3333
* `crates.io <https://crates.io/>`_ is where third party crates (libraries) are stored and distributed.
34-
This contains links to the documentation on each crate.
35-
* Likewise the python/rust build system can be found at `maturin <https://www.maturin.rs/>`_
36-
* Documentation for the python binding engine PyO3 can be found `here <https://docs.rs/pyo3/latest/pyo3/>`_
34+
This contains links to the documentation on each crate.
35+
* Likewise the Python/Rust build system can be found at `maturin <https://www.maturin.rs/>`_
36+
* Documentation for the Python binding engine PyO3 can be found `here <https://docs.rs/pyo3/latest/pyo3/>`__
3737

3838
4. Code Organization
3939
--------------------
4040

41-
Unlike the package-centric organization often seen in Python, packages containing rust code should be monolithic and not depend on other lsst packages.
41+
Unlike the package-centric organization often seen in Python, packages containing Rust code should be monolithic and not depend on other lsst packages.
4242

4343
* Top-Level Module: All Rust code will be bound to a single top-level module.
4444
This module will serve as the entry point for Python interaction.
@@ -49,70 +49,70 @@ Unlike the package-centric organization often seen in Python, packages containin
4949
5. Python Interoperability
5050
--------------------------
5151

52-
All Rust code intended for use within the LSST DM Stack must be exposed to Python via a well-defined API. This is achieved using the `pyO3`_ bindings.
52+
All Rust code intended for use within the LSST DM Stack must be exposed to Python via a well-defined API. This is achieved using the `pyO3`_ bindings.
5353

54-
* `pyO3`_ is Mandatory: `pyO3`_ is the only supported mechanism for exposing Rust functionality to Python.
54+
* `pyO3`_ is Mandatory: `pyO3`_ is the only supported mechanism for exposing Rust functionality to Python.
5555
* API Design: Rust-implemented Python functions and types should adhere to Python interface best practices instead of maximizing similarity to other internal Rust interfaces.
56-
* Documentation: Thoroughly document your Python API using docstrings. Docstrings are written as doc comments in the rust and are automatically translated to python docstrings by pyO3. Doc strings should be written in the same numpydoc format as specified in the python section of the devguide.
56+
* Documentation: Thoroughly document your Python API using docstrings. Docstrings are written as doc comments in the Rust and are automatically translated to Python docstrings by pyO3. Doc strings should be written in the same ``numpydoc`` format as specified in `the Python section <python/numpydoc.rst>`__ of this Developer Guide.
5757

5858
6. Dependencies
5959
---------------
6060

61-
Managing dependencies is crucial for maintaining a stable and reproducible build environment.
61+
Managing dependencies is crucial for maintaining a stable and reproducible build environment.
6262

63-
* RFC Process: All new Rust dependencies added to the Cargo.toml file must be approved via the LSST RFC (Request for Comments) process.
64-
This ensures that dependencies are vetted for licensing, security, and long-term maintainability.
65-
* Dependency Versions: Pin dependency versions in Cargo.toml to ensure reproducible builds with exact pins.
63+
* RFC Process: All new Rust dependencies added to the Cargo.toml file must be approved via the LSST RFC (Request for Comments) process and the DM CCB (Change Control Board).
64+
This ensures that dependencies are vetted for licensing, security, and long-term maintainability.
65+
* Dependency Versions: Pin dependency versions in Cargo.toml to ensure reproducible builds with exact pins.
6666
As the Cargo.lock file is also committed to git, this ensures all builds remain on equal footing.
67-
Incrementing version should be done on a standalone commit after evaluating the effect on compiling and packaging.
67+
Incrementing versions should be done on a standalone commit after evaluating the effect on compiling and packaging.
6868

6969
7. Testing
7070
----------
7171

7272
* Python Unit Tests: All Rust code with a Python interface must be tested via Python unit tests.
7373
This provides a consistent testing framework and leverages the existing LSST testing infrastructure.
74-
These tests should be placed in the **tests** top level directory.
75-
* pytest: Use pytest as the python testing framework.
76-
* For functionality that does not have a public python api, or is not well covered by a python api, or is difficult to appropriately test with a python unit test rust unit tests may be written using the standard rust unit test infrastructure.
77-
Generally avoid a rust unit tests on any code that is wrapped with pyo3.
78-
* Import Rust Modules: Python tests should import the Rust modules (exposed via `pyO3`_) and exercise their functionality.
79-
* Comprehensive Coverage: Strive for high test coverage to ensure that all critical code paths are tested.
74+
These tests should be placed in the ``tests`` top level directory.
75+
* ``pytest``: Use ``pytest`` as the Python testing framework.
76+
* For functionality that does not have a public Python api, or is not well covered by a Python api, or is difficult to appropriately test with a Python unit test, Rust unit tests may be written using the standard Rust unit test infrastructure.
77+
Generally avoid Rust unit tests on any code that is wrapped with `pyO3`_.
78+
* Import Rust Modules: Python tests should import the Rust modules (exposed via `pyO3`_) and exercise their functionality.
79+
* Comprehensive Coverage: Strive for high test coverage to ensure that all critical code paths are tested.
8080
* Integration Tests: In addition to unit tests, consider integration tests to verify the interaction between Rust components and other parts of the LSST DM Stack.
8181

8282
8. Code Style and Formatting
8383
----------------------------
8484

85-
Consistent code style improves readability and maintainability.
85+
Consistent code style improves readability and maintainability.
8686

87-
* `rustfmt`_: One must use rustfmt to automatically format your Rust code, or otherwise produce output that is the same as would have been produced with `rustfmt`_.
88-
* `Clippy`_: Use Clippy to lint your Rust code and identify potential issues. Not every suggestion from clippy must be adopted, but all should be carefully considered. Suggestions which make code conform to community standards should only be skipped with good justification.
89-
* Documentation Comments: Write clear and concise documentation comments for all public functions and data structures.
90-
* To the extent possible, make apis that will be public to python feel exactly as if they are written in python.
87+
* `rustfmt`_: One must use `rustfmt`_ to automatically format your Rust code, or otherwise produce output that is the same as would have been produced with `rustfmt`_.
88+
* `Clippy`_: Use Clippy to lint your Rust code and identify potential issues. Not every suggestion from Clippy must be adopted, but all should be carefully considered. Suggestions which make code conform to community standards should only be skipped with good justification.
89+
* Documentation Comments: Write clear and concise documentation comments for all public functions and data structures.
90+
* To the extent possible, make APIs that will be public to Python feel exactly as if they are written in Python.
9191

9292
9. Logging
9393
-----------
9494

9595
Logging should be done using the `log`_ crate, and accompanying macros.
96-
The standard rubinoxide package initializes the pyo3_log crate to forward all logs through to the python log handler to the appropriate log level.
96+
The standard ``rubinoxide`` package initializes the ``pyo3_log`` crate to forward all logs through to the Python log handler to the appropriate log level.
9797

9898
10. Don'ts
9999
----------
100100

101-
* Do not use implicit multithreading in rust
102-
* Do not introduce any cross package rust bindings that transit through python aka how we use c++ now.
101+
* Do not use implicit multithreading in Rust.
102+
* Do not introduce any cross package Rust bindings that transit through Python (do not emulate current C++ practice).
103103
* As mentioned above, do not arrange module structure according to lsst packages. Write modules by related functionality.
104104

105105
11. Build and management system integration
106106
-------------------------------------------
107107

108-
* Rust packages should be built using maturin, which manages the complexities of compiling and bundling cargo products.
109-
* Cargo additionally is to be used manage dependencies and run rust level tests.
110-
* pip is used as the mechanism to locally deploy the wheels created by maturin
111-
* pytest is used to run python level unit tests
112-
* coordinating these scripts for the developer is a Makefile
113-
* The Makefile supports build and test modes independently (as well as an all mode) so authors can more quickly iterate in development.
108+
* Rust packages should be built using ``maturin``, which manages the complexities of compiling and bundling cargo products.
109+
* Cargo additionally is to be used manage dependencies and run Rust level tests.
110+
* ``pip`` is used as the mechanism to locally deploy the wheels created by ``maturin``.
111+
* ``pytest`` is used to run Python level unit tests.
112+
* Coordinating these scripts for the developer is a ``Makefile``.
113+
* The ``Makefile`` supports ``build`` and ``test`` modes independently (as well as an ``all`` mode) so authors can more quickly iterate in development.
114114

115-
.. _rustfmt: https://github.com/rust-lang/rustfmt
115+
.. _rustfmt: https://github.com/rust-lang/rustfmt
116116
.. _Clippy: https://github.com/rust-lang/rust-clippy
117117
.. _pyO3: https://pyo3.rs/
118118
.. _log: https://docs.rs/log/latest/log/

0 commit comments

Comments
 (0)