pamoja-serial
SLIP and COBS byte stuffing with streaming decoders, so a UART byte stream carries discrete packets. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
Install
pip install pamoja-serial
from pamoja import serial
This pulls in pamoja-native, the compiled engine. pip install pamoja is the whole framework in one package.
Example
The script the test suite runs, spliced here as it ran.
From bindings/python/guides/serial.py:
from pamoja.serial import COBS_DELIMITER, SLIP_END, SLIP_ESC, SlipDecoder, cobs, slip
# A UART carries bytes, not packets, so a framing has to mark where one packet ends. SLIP
# reserves two byte values for that, and the package names both: the end byte closes a
# frame, the escape byte carries a value that would otherwise look like one.
payload = b"lvl=" + bytes([SLIP_END, SLIP_ESC])
framed = slip.encode(payload)
print(f"slip {len(payload)} payload bytes framed as {len(framed)}")
# Decoding gives the payload back unchanged, reserved bytes and all.
restored = slip.decode(framed)
print(f"slip decoded back to {len(restored)} bytes")
# COBS trades that escaping for one code byte per run of up to 254 non-zero bytes, each
# run led by its own length, so a frame never grows by more than a byte per 254. Zero is
# the delimiter, and never appears inside a frame.
packet = b"lvl=" + bytes([COBS_DELIMITER]) + b"7"
cobs_framed = cobs.encode(packet)
print(f"cobs {len(packet)} payload bytes framed as {len(cobs_framed)}")
# A read from a port returns whatever arrived, which is rarely one whole frame. This chunk
# holds two good frames with a truncated one between them; the decoder hands over the good
# ones and discards only the bad frame.
decoder = SlipDecoder()
chunk = (
b"ok"
+ bytes([SLIP_END])
+ bytes([SLIP_ESC]) # a frame that ends before its escape pair completes
+ bytes([SLIP_END])
+ b"go"
+ bytes([SLIP_END])
)
frames = decoder.feed(chunk)
for frame in frames:
print(f"received {frame.decode()}")
print(f"discarded {decoder.discarded} frame the stream mangled")
The same capability in every language
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-serial |
reference, docs.rs, install |
| TypeScript | @pamoja/serial |
reference, install |
| Python | pamoja-serial |
reference, install |
| C# | Pamoja.Serial |
reference, install |
Documentation
pamoja.serialreference, every class and function in this module.- The Serial framing guide, with the same example in Rust, TypeScript, and C#.
- Every capability, and the install page.
License
MIT
Release files for pamoja-serial 0.1.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pamoja_serial-0.1.18.tar.gz | 4.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pamoja_serial-0.1.18-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.0 kB
Release files / pamoja_serial-0.1.18.tar.gz
| Download URL | pamoja_serial-0.1.18.tar.gz |
|---|---|
| Size | 4.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
98c461702fde706a18f60f1305315bb62cf02e944222f5a5ec95a754df4cda23
|
|
BLAKE2b-256 checksum How to use checksums |
2453295e5908fdabf6260854ae9d9a553df40b05a85577f1ec8f95a57e10466c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Release files / pamoja_serial-0.1.18-py3-none-any.whl
| Download URL | pamoja_serial-0.1.18-py3-none-any.whl |
|---|---|
| Size | 5.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3eda689902b016cbbec0c31ff9f4708a1c1c5a5da29c3efd8a3264c0e437eaea
|
|
BLAKE2b-256 checksum How to use checksums |
c9cb5aa4c6d9a6408c333db936f19de49d9faeead294ab48e85324f0e92ab42b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|