diff --git a/bindings/node/src/config.rs b/bindings/node/src/config.rs index e3ab2c1..362348b 100644 --- a/bindings/node/src/config.rs +++ b/bindings/node/src/config.rs @@ -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. diff --git a/bindings/python/src/config.rs b/bindings/python/src/config.rs index 42fe706..7dd17fa 100644 --- a/bindings/python/src/config.rs +++ b/bindings/python/src/config.rs @@ -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 | /// |--------:|:--------------| diff --git a/docs/scripts/html_sanitizer.py b/docs/scripts/html_sanitizer.py index e144c9f..a9e5b25 100644 --- a/docs/scripts/html_sanitizer.py +++ b/docs/scripts/html_sanitizer.py @@ -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) diff --git a/docs/scripts/py_native_docstring.py b/docs/scripts/py_native_docstring.py index d950568..c89526c 100644 --- a/docs/scripts/py_native_docstring.py +++ b/docs/scripts/py_native_docstring.py @@ -13,6 +13,7 @@ """ import ast +from typing import cast import griffe import importlib import logging @@ -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. @@ -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, @@ -76,7 +79,7 @@ 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, @@ -84,12 +87,12 @@ def on_function_node( """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": diff --git a/docs/src/api-diff.md b/docs/src/api-diff.md index addf243..8551a09 100644 --- a/docs/src/api-diff.md +++ b/docs/src/api-diff.md @@ -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 @@ -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). @@ -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 @@ -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}} ```