An address is packed segment records (Rust)

path_to_tlv("/sensor/temp") builds the PATH TLV every request names its target with. Its body is the RFC-0018 packed form: a length byte, then the segment’s bytes, repeated.

What to notice

  • No separators, no terminator. /sensor/temp becomes [6]sensor[4]temp, twelve bytes. On a node that body is the vertex-map key, so one address has exactly one spelling.

  • Rendering gives the canonical string back. tlv_to_path turns the decoded TLV into /sensor/temp, and a trailing slash splits to the same segments.

  • A relative path is not an address. path_to_tlv("sensor/temp") answers BuildError::NotRooted instead of guessing a root.

Source

 1// SPDX-License-Identifier: Apache-2.0
 2// SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
 3
 4/*!
 5 * @brief One concept: an address is a PATH TLV whose body is packed segment records,
 6 * one length byte then the segment's bytes (RFC-0018).
 7 *
 8 * Run: `cargo run --example path_tlv` (from `bindings/rust/`).
 9 */
10
11use libtracer::path::{path_to_tlv, split_path, tlv_to_path};
12use libtracer::{decode, encode, type_code, BuildError};
13
14fn main() {
15    let tlv = path_to_tlv("/sensor/temp").expect("a rooted, valid path");
16    assert_eq!(tlv.type_code, type_code::PATH);
17
18    // The body: [6]"sensor" [4]"temp". No separators, no terminator.
19    let mut body = vec![6u8];
20    body.extend_from_slice(b"sensor");
21    body.push(4);
22    body.extend_from_slice(b"temp");
23    assert_eq!(tlv.payload, body);
24    println!(
25        "PATH body ({} bytes): {:02x?}",
26        tlv.payload.len(),
27        tlv.payload
28    );
29
30    // On the wire it is an ordinary opaque TLV: 4-byte header + body.
31    let frame = encode(&tlv);
32    assert_eq!(frame.len(), 4 + body.len());
33
34    // Decoding and rendering gives back the one canonical spelling.
35    let back = tlv_to_path(&decode(&frame).unwrap()).unwrap();
36    assert_eq!(back, "/sensor/temp");
37    println!("round trip: {back}");
38
39    // A trailing slash is the same address; a relative one is no address at all.
40    assert_eq!(split_path("/sensor/temp/").unwrap(), ["sensor", "temp"]);
41    assert_eq!(path_to_tlv("sensor/temp"), Err(BuildError::NotRooted));
42    println!("\"sensor/temp\" -> NotRooted");
43}

Run it from bindings/rust/:

$ cargo run --example path_tlv

See also: packed PATH (C++) · addressing reference.