Skip to content

Commit 5d72dee

Browse files
committed
Improve developer guide code style and conventions for Rust
1 parent 605fe65 commit 5d72dee

File tree

2 files changed

+98
-34
lines changed

2 files changed

+98
-34
lines changed

docs/developer_guide/coding_standards.md

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -73,40 +73,6 @@ class ThrottledEnqueuer(Generic[T]):
7373
The [NumPy docstring spec](https://numpydoc.readthedocs.io/en/latest/format.html) is used throughout the codebase.
7474
This needs to be adhered to consistently to ensure the docs build correctly.
7575

76-
**Comprehensive docstring structure**:
77-
78-
```python
79-
def calculate_balance(
80-
self,
81-
instrument: Instrument,
82-
side: OrderSide,
83-
quantity: Quantity,
84-
) -> Money:
85-
"""
86-
Calculate the balance for the given parameters.
87-
88-
Parameters
89-
----------
90-
instrument : Instrument
91-
The instrument for the calculation.
92-
side : OrderSide
93-
The order side.
94-
quantity : Quantity
95-
The order quantity.
96-
97-
Returns
98-
-------
99-
Money
100-
The calculated balance.
101-
102-
Raises
103-
------
104-
ValueError
105-
If the quantity is invalid.
106-
107-
"""
108-
```
109-
11076
**Test method naming**: Descriptive names explaining the scenario:
11177

11278
```python

docs/developer_guide/rust.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@ Python bindings are provided via Cython and [PyO3](https://pyo3.rs), allowing us
88

99
## Code Style and Conventions
1010

11+
### File Header Requirements
12+
13+
All Rust files must include the standardized copyright header:
14+
15+
```rust
16+
// -------------------------------------------------------------------------------------------------
17+
// Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
18+
// https://nautechsystems.io
19+
//
20+
// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
21+
// You may not use this file except in compliance with the License.
22+
// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
23+
//
24+
// Unless required by applicable law or agreed to in writing, software
25+
// distributed under the License is distributed on an "AS IS" BASIS,
26+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27+
// See the License for the specific language governing permissions and
28+
// limitations under the License.
29+
// -------------------------------------------------------------------------------------------------
30+
```
31+
32+
### Code Formatting
33+
34+
Import formatting is automatically handled by rustfmt when running `make format`. The tool organizes imports into groups (standard library, external crates, local imports) and sorts them alphabetically within each group.
35+
1136
### Error Handling
1237

1338
Use structured error handling patterns consistently:
@@ -69,6 +94,79 @@ pub fn base_balance(&self, currency: Option<Currency>) -> Option<&AccountBalance
6994
}
7095
```
7196

97+
#### Errors and Panics Documentation Format
98+
99+
For single line errors and panics documentation, use sentence case with the following convention:
100+
101+
```rust
102+
/// Returns a reference to the `AccountBalance` for the specified currency, or `None` if absent.
103+
///
104+
/// # Errors
105+
///
106+
/// Returns an error if the currency conversion fails.
107+
///
108+
/// # Panics
109+
///
110+
/// Panics if `currency` is `None` and `self.base_currency` is `None`.
111+
pub fn base_balance(&self, currency: Option<Currency>) -> anyhow::Result<Option<&AccountBalance>> {
112+
// Implementation
113+
}
114+
```
115+
116+
For multi-line errors and panics documentation, use sentence case with bullets and terminating periods:
117+
118+
```rust
119+
/// Calculates the unrealized profit and loss for the position.
120+
///
121+
/// # Errors
122+
///
123+
/// This function will return an error if:
124+
/// - The market price for the instrument cannot be found.
125+
/// - The conversion rate calculation fails.
126+
/// - Invalid position state is encountered.
127+
///
128+
/// # Panics
129+
///
130+
/// This function will panic if:
131+
/// - The instrument ID is invalid or uninitialized.
132+
/// - Required market data is missing from the cache.
133+
/// - Internal state consistency checks fail.
134+
pub fn calculate_unrealized_pnl(&self, market_price: Price) -> anyhow::Result<Money> {
135+
// Implementation
136+
}
137+
```
138+
139+
#### Safety Documentation Format
140+
141+
For Safety documentation, use the `SAFETY:` prefix followed by a short description explaining why the unsafe operation is valid:
142+
143+
```rust
144+
/// Creates a new instance from raw components without validation.
145+
///
146+
/// # Safety
147+
///
148+
/// The caller must ensure that all input parameters are valid and properly initialized.
149+
pub unsafe fn from_raw_parts(ptr: *const u8, len: usize) -> Self {
150+
// SAFETY: Caller guarantees ptr is valid and len is correct
151+
Self {
152+
data: std::slice::from_raw_parts(ptr, len),
153+
}
154+
}
155+
```
156+
157+
For inline unsafe blocks, use the `SAFETY:` comment directly above the unsafe code:
158+
159+
```rust
160+
impl Send for MessageBus {
161+
fn send(&self) {
162+
// SAFETY: Message bus is not meant to be passed between threads
163+
unsafe {
164+
// unsafe operation here
165+
}
166+
}
167+
}
168+
```
169+
72170
### Testing Conventions
73171

74172
#### Test Organization

0 commit comments

Comments
 (0)