dbus
stableD-Bus wire protocol helpers for encoding/decoding strings, integers, booleans, and signatures, and for building typed message descriptor tables.
use plugin dbus::{encode_string, decode_string, encode_signature, …} Functions (19)
- encode_string Encode a string to D-Bus wire format bytes
- decode_string Decode D-Bus wire format bytes to a string
- encode_signature Encode a type signature to wire format bytes
- message_type_name Get the name for a D-Bus message type integer
- build_method_call Build a METHOD_CALL message descriptor
- build_signal Build a SIGNAL message descriptor
- build_error Build an ERROR message descriptor
- build_method_return Build a METHOD_RETURN message descriptor
- object_path_valid Validate a D-Bus object path
- interface_name_valid Validate a D-Bus interface name
- bus_name_valid Validate a D-Bus bus name
- member_name_valid Validate a D-Bus member name
- encode_uint32 Encode a uint32 to 4-byte little-endian bytes
- decode_uint32 Decode 4-byte little-endian bytes to an integer
- encode_int32 Encode an int32 to 4-byte little-endian bytes
- decode_int32 Decode 4-byte little-endian bytes to a signed int
- encode_boolean Encode a boolean to 4-byte D-Bus format
- decode_boolean Decode 4-byte D-Bus format to a boolean
- signature_type_name Get the type name for a D-Bus signature char
Overview
The dbus plugin provides low-level helpers for working with the D-Bus wire
protocol without a running message bus. It does two things: it encodes and
decodes primitive values (strings, signatures, uint32, int32, booleans)
to and from their exact byte layouts, and it builds message descriptor tables
(method calls, signals, errors, method returns) plus a set of validators for
D-Bus names and object paths. Everything is stateless — there are no handles
or connections; each function takes plain values and returns bytes, tables,
strings, or booleans. Reach for it when you need to inspect, assemble, or
validate D-Bus messages by hand, e.g. in tooling, tests, or a custom
transport layer.
Common patterns
Round-trip a primitive value through the wire format:
use plugin dbus::{encode_uint32, decode_uint32, encode_string, decode_string}
let n = encode_uint32(4242)
print("uint32 round-trips: {decode_uint32(n)}")
let s = encode_string("org.freedesktop.DBus")
print("string round-trips: {decode_string(s)}")
Validate the parts of a call before building its descriptor:
use plugin dbus::{object_path_valid, interface_name_valid, member_name_valid, build_method_call}
let path = "/org/freedesktop/DBus"
let iface = "org.freedesktop.DBus"
let member = "ListNames"
if object_path_valid(path) and interface_name_valid(iface) and member_name_valid(member) {
let msg = build_method_call(path, iface, member)
print("calling {msg["interface"]}.{msg["member"]}")
}
Decode a message type id and a signature into readable names:
use plugin dbus::{message_type_name, signature_type_name}
print("message: {message_type_name(1)}")
print("first arg: {signature_type_name("s")}")
print("second arg: {signature_type_name("u")}")
Encode a string to D-Bus wire format bytes
Encodes a string to the D-Bus wire format: a 4-byte little-endian length prefix, the UTF-8 content bytes, and a null terminator byte.
use plugin dbus::{encode_string, decode_string}
let encoded = encode_string("Hello D-Bus")
let decoded = decode_string(encoded)
print(decoded)
The first four bytes are the little-endian length, so the encoded buffer is
always 4 + len + 1 bytes long (the trailing byte is a null terminator):
use plugin dbus::{encode_string}
let bytes = encode_string("hi")
print("buffer length: {#bytes}")
Decode D-Bus wire format bytes to a string
Decodes a D-Bus wire-format string (4-byte length + data + null) back to a Zolo string.
use plugin dbus::{encode_string, decode_string}
let raw = encode_string("org.freedesktop.DBus")
let name = decode_string(raw)
print(name)
Encode a type signature to wire format bytes
Encodes a D-Bus type signature string to wire format: a 1-byte length prefix, the ASCII content bytes, and a null terminator.
use plugin dbus::{encode_signature}
let sig = encode_signature("su")
print("sig bytes: {#sig}")
Get the name for a D-Bus message type integer
Returns the human-readable name for a D-Bus message type integer.
0=INVALID, 1=METHOD_CALL, 2=METHOD_RETURN, 3=ERROR, 4=SIGNAL.
use plugin dbus::{message_type_name}
print(message_type_name(1))
print(message_type_name(4))
print(message_type_name(99))
Build a METHOD_CALL message descriptor
Builds a method call message descriptor table with type, type_id, path,
interface, and member fields. Use this to describe a call before
serialising it to bytes.
use plugin dbus::{build_method_call}
let msg = build_method_call(
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames"
)
print("type: {msg["type"]}")
print("member: {msg["member"]}")
The returned table also carries the numeric type_id (1 for a method call),
which you can feed back into message_type_name:
use plugin dbus::{build_method_call, message_type_name}
let msg = build_method_call("/org/example", "org.example.App", "Ping")
print("kind: {message_type_name(msg["type_id"])}")
Build a SIGNAL message descriptor
Builds a signal message descriptor table with type set to "SIGNAL" and
type_id set to 4.
use plugin dbus::{build_signal}
let sig = build_signal(
"/com/example/App",
"com.example.App",
"DataChanged"
)
print("type: {sig["type"]}")
Build an ERROR message descriptor
Builds an error message descriptor with type, type_id, error_name, and
error_message fields. error_message is optional and defaults to "".
use plugin dbus::{build_error}
let err = build_error("org.freedesktop.DBus.Error.Failed", "not found")
print("{err["error_name"]}: {err["error_message"]}")
Build a METHOD_RETURN message descriptor
Builds a method return message descriptor for the given reply serial number.
use plugin dbus::{build_method_return}
let reply = build_method_return(42)
print("type: {reply["type"]}, serial: {reply["reply_serial"]}")
Validate a D-Bus object path
Returns true if path is a valid D-Bus object path. A valid path starts with
/, uses only [A-Za-z0-9_] in each segment, and does not end with /
(except the root /).
use plugin dbus::{object_path_valid}
print(object_path_valid("/"))
print(object_path_valid("/org/freedesktop/DBus"))
print(object_path_valid("/bad path/"))
Use it as a guard before constructing a descriptor so you never build a message with an illegal path:
use plugin dbus::{object_path_valid, build_signal}
let path = "/com/example/App"
if object_path_valid(path) {
let sig = build_signal(path, "com.example.App", "Ready")
print("emitting {sig["member"]}")
}
Validate a D-Bus interface name
Returns true if name is a valid D-Bus interface name: at least two
dot-separated elements, each containing only [A-Za-z0-9_] and not starting
with a digit, and total length at most 255.
use plugin dbus::{interface_name_valid}
print(interface_name_valid("org.freedesktop.DBus"))
print(interface_name_valid("invalid"))
print(interface_name_valid("1bad.name"))
Validate a D-Bus bus name
Returns true if name is a valid D-Bus bus name (well-known or unique).
Well-known names follow the same rules as interface names. Unique names start
with : followed by dot-separated alphanumeric elements.
use plugin dbus::{bus_name_valid}
print(bus_name_valid("org.freedesktop.DBus"))
print(bus_name_valid(":1.42"))
print(bus_name_valid("bad"))
Validate a D-Bus member name
Returns true if name is a valid D-Bus member name: non-empty, at most 255
characters, contains only [A-Za-z0-9_], and does not start with a digit.
use plugin dbus::{member_name_valid}
print(member_name_valid("ListNames"))
print(member_name_valid("Get"))
print(member_name_valid("1BadName"))
Encode a uint32 to 4-byte little-endian bytes
Encodes an unsigned 32-bit integer to 4 bytes in little-endian order.
use plugin dbus::{encode_uint32, decode_uint32}
let bytes = encode_uint32(12345)
let back = decode_uint32(bytes)
print("value: {back}")
Decode 4-byte little-endian bytes to an integer
Decodes 4 little-endian bytes to an unsigned 32-bit integer.
use plugin dbus::{encode_uint32, decode_uint32}
let encoded = encode_uint32(0xDEAD)
print("decoded: {decode_uint32(encoded)}")
Encode an int32 to 4-byte little-endian bytes
Encodes a signed 32-bit integer to 4 bytes in little-endian order.
use plugin dbus::{encode_int32, decode_int32}
let bytes = encode_int32(-100)
let back = decode_int32(bytes)
print("value: {back}")
Decode 4-byte little-endian bytes to a signed int
Decodes 4 little-endian bytes to a signed 32-bit integer.
use plugin dbus::{encode_int32, decode_int32}
let encoded = encode_int32(-42)
print("decoded: {decode_int32(encoded)}")
Encode a boolean to 4-byte D-Bus format
Encodes a boolean to the D-Bus 4-byte boolean wire format (0x00000000 for
false, 0x01000000 for true, little-endian).
use plugin dbus::{encode_boolean, decode_boolean}
let t = encode_boolean(true)
let f = encode_boolean(false)
print("true: {decode_boolean(t)}")
print("false: {decode_boolean(f)}")
Decode 4-byte D-Bus format to a boolean
Decodes 4 little-endian bytes from D-Bus boolean wire format. Returns true if the uint32 value is non-zero.
use plugin dbus::{encode_boolean, decode_boolean}
let raw = encode_boolean(true)
print(decode_boolean(raw))
Get the type name for a D-Bus signature char
Returns the human-readable D-Bus type name for a single signature character,
e.g. "s" → "STRING", "i" → "INT32", "a" → "ARRAY".
use plugin dbus::{signature_type_name}
print(signature_type_name("s"))
print(signature_type_name("u"))
print(signature_type_name("a"))
print(signature_type_name("v"))
Container characters map to their structural names, and anything unrecognised
returns "UNKNOWN":
use plugin dbus::{signature_type_name}
print(signature_type_name("("))
print(signature_type_name("{"))
print(signature_type_name("z"))