Skip to content

Commit

Permalink
some docs review
Browse files Browse the repository at this point in the history
  • Loading branch information
2bndy5 committed Dec 30, 2024
1 parent 60b524a commit 2a54b9f
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 27 deletions.
4 changes: 2 additions & 2 deletions bindings/node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ impl RadioConfig {
///
/// To enable the feature for pipes 0, 1 and 4:
/// ```js
/// let config = RadioConfig()
/// config.auto_ack = 0b010011
/// let config = new RadioConfig();
/// config.auto_ack = 0b010011;
/// ```
/// If enabling the feature for any pipe other than 0, then the pipe 0 should also have the
/// feature enabled because pipe 0 is used to transmit automatic ACK packets in RX mode.
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rf24::radio::EsbConfig;

use std::borrow::Cow;

/// Instantiate a [`RadioConfig`] object with library defaults.
/// Instantiate a [`RadioConfig`][rf24_py.RadioConfig] object with library defaults.
///
/// | feature | default value |
/// |--------:|:--------------|
Expand Down
4 changes: 2 additions & 2 deletions docs/scripts/html_sanitizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from mkdocs.structure.files import Files
from mkdocs.config.defaults import MkDocsConfig

DEFINED_IN_PATTERN = re.compile(r"#### Defined in\n\nindex\.d\.ts\:\d+")
SECTIONS_PATTERN = re.compile(r"#### (Parameters|Returns|Throws)")
DEFINED_IN_PATTERN = re.compile(r"#+ Defined in\n\nindex\.d\.ts\:\d+")
SECTIONS_PATTERN = re.compile(r"#+ (Parameters|Returns|Throws)")
LIST_MARKER_PATTERN = re.compile("^• ", re.MULTILINE)
GROUP_API_PATTERN = re.compile(r"^## \w+\s*$", re.MULTILINE)

Expand Down
19 changes: 11 additions & 8 deletions docs/scripts/py_native_docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""

import ast
from typing import cast
import griffe
import importlib
import logging
Expand All @@ -34,7 +35,7 @@ def elide_signature_from_docstring(docstring: str) -> str:
return "\n".join(lines[start:])


def inject_docstring(node: ast.AST, native_doc: str | None):
def inject_docstring(node: ast.FunctionDef | ast.ClassDef, native_doc: str):
"""Inject a given `native_docstring` into the AST node's body.
Tested only with ClassDef and FunctionDef AST nodes.
Expand All @@ -48,15 +49,17 @@ def inject_docstring(node: ast.AST, native_doc: str | None):
wrapper_node = ast.Expr(new_node)
ast.copy_location(wrapper_node, node)
node.body.insert(0, wrapper_node)
elif node.body[0].value.value != native_doc:
node.body[0].value.value = native_doc + docstring
elif cast(ast.Constant, cast(ast.Expr, node.body[0]).value).value != native_doc:
cast(ast.Constant, cast(ast.Expr, node.body[0]).value).value = (
native_doc + docstring
)


class NativeDocstring(griffe.Extension):
def __init__(self):
self.native = importlib.import_module("rf24_py")

def on_class_node(
def on_class_node( # type: ignore[override]
self,
node: ast.ClassDef | griffe.ObjectNode,
agent: griffe.Visitor | griffe.Inspector,
Expand All @@ -76,20 +79,20 @@ def on_class_node(
# print(f"Amending docstring for rf24_py.{node.name}")
inject_docstring(node, native_doc)

def on_function_node(
def on_function_node( # type: ignore[override]
self,
node: ast.FunctionDef | griffe.ObjectNode,
agent: griffe.Visitor | griffe.Inspector,
) -> None:
"""Prepend a docstring from the native module"""
if isinstance(node, griffe.ObjectNode):
return # any docstring fetched from pure python should be adequate
if not isinstance(node.parent, ast.ClassDef):
if not isinstance(node.parent, ast.ClassDef): # type: ignore[attr-defined]
return # we're only concerned with class methods here
func_parent = node.parent
func_parent = node.parent # type: ignore[attr-defined]
native_cls = getattr(self.native, func_parent.name)
native_obj = getattr(native_cls, node.name)
native_doc: str | None = native_obj.__doc__
native_doc: str = native_obj.__doc__ or ""
if node.decorator_list:
for dec in node.decorator_list:
if isinstance(dec, ast.Name) and dec.id == "property":
Expand Down
25 changes: 11 additions & 14 deletions docs/src/api-diff.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,20 @@ If dynamic payloads are enabled then setting static payload size has no affect.

## STATUS byte exposed

As with our other implementations, the STATUS byte returned on every SPI transaction is cached to a private member. Understanding the meaning of the status byte is publicly exposed via
As with our other implementations, the STATUS byte returned on every SPI transaction is cached to a private member.
Understanding the meaning of the status byte is publicly exposed via

- `update()`: used to get an update about the status flags from the radio.
- `clear_status_flags()`: with parameters to specify which flag(s) should be cleared.
- `get_status_flags()`: has a signature similar to C++ `whatHappened()` but does not update nor clear the flags.
- `clear_status_flags()`: used to specify which flag(s) should be cleared.
- `get_status_flags()`: similar to C++ `whatHappened()` but does not update nor clear the flags.
- `set_status_flags()`: similar to C++ `maskIRQ()` except the boolean parameters' meaning is not reversed.

| lang | only trigger on RX_DR events |
|:----:|:-----------------------------|
| C++ | `radio.maskIRQ(false, true, true)` |
| Rust | `radio.set_status_flags(true, false, false)` |
| Rust | `radio.set_status_flags(StatusFlags::default().with_rx_dr(true)` |

In this library, passing `true` to any parameter of `set_stats_flags()` will enable the IRQ for the corresponding event (see function's documentation).
In this library, setting and getting the status flags is done with a `StatusFlags` object.

## No babysitting

Expand All @@ -47,7 +48,9 @@ To transmit something, RF24 struct offers
- `send()`: blocking wrapper around `write()`
- `write()`: non-blocking uploads to TX FIFO.

Use `update()` and `get_status_flags()` get the updated status flags to determine if transmission was successful or not. The IRQ pin can also be used to trigger calls to `update()` + `get_status_flags()`. See `set_status_flags()` about configuring the IRQ pin.
Use `update()` and `get_status_flags()` to determine if transmission was successful or not.
The IRQ pin can also be used to trigger calls to `update()` + `get_status_flags()`.
See `set_status_flags()` about configuring the IRQ pin.

There will be no equivalents to C++ `writeBlocking()`, `startFastWrite()`, `writeFast()`, `txStandby()`.
Considering the exposed STATUS byte, these can all be done from the user space (if needed).
Expand All @@ -56,13 +59,7 @@ Additionally, `send()` does _**not**_ implement a timeout.
Every member function in the `RF24` struct (except the `new()`) returns a [`Result`][result],
so problems with the SPI connections should be detected early in the app lifecycle.
The rustc compiler will warn users about unhandled [`Result`][result]s.

As an alternative, I've been considering an optional `irq_pin` parameter to the constructor.
If specified in user code, then `send()` shall wait for the IRQ pin to become active instead of pinging the radio's STATUS byte over SPI.

> [!TIP]
> Rust does offer a way to overload functions using [traits] (feature akin to C++ templates),
> but it isn't traditionally relied upon in a public API.
In the Python and Node.js bindings, an exception is thrown when hardware misbehavior is detected.

## API structure

Expand All @@ -77,9 +74,9 @@ flowchart TD
esb("EsbRadio (trait)") --> RF24
esb --> nrf51{{RF51}}
esb --> nrf52{{RF52}}
esb--> ble{{FakeBle}}
end
RF24 --> ble{{FakeBle}}
radio --> net{{RF24Network}}
net --> mesh{{RF24Mesh}}
```
Expand Down

0 comments on commit 2a54b9f

Please sign in to comment.