Skip to content

dbus

stable

D-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, …}
19 functions Systems
/ filter jk navigate Esc clear
Functions (19)
  1. encode_string Encode a string to D-Bus wire format bytes
  2. decode_string Decode D-Bus wire format bytes to a string
  3. encode_signature Encode a type signature to wire format bytes
  4. message_type_name Get the name for a D-Bus message type integer
  5. build_method_call Build a METHOD_CALL message descriptor
  6. build_signal Build a SIGNAL message descriptor
  7. build_error Build an ERROR message descriptor
  8. build_method_return Build a METHOD_RETURN message descriptor
  9. object_path_valid Validate a D-Bus object path
  10. interface_name_valid Validate a D-Bus interface name
  11. bus_name_valid Validate a D-Bus bus name
  12. member_name_valid Validate a D-Bus member name
  13. encode_uint32 Encode a uint32 to 4-byte little-endian bytes
  14. decode_uint32 Decode 4-byte little-endian bytes to an integer
  15. encode_int32 Encode an int32 to 4-byte little-endian bytes
  16. decode_int32 Decode 4-byte little-endian bytes to a signed int
  17. encode_boolean Encode a boolean to 4-byte D-Bus format
  18. decode_boolean Decode 4-byte D-Bus format to a boolean
  19. 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"))
enespt-br