serde-txtrecord

Crates.ioserde-txtrecord
lib.rsserde-txtrecord
version0.1.0
created_at2025-08-05 20:52:46.566732+00
updated_at2025-08-05 20:52:46.566732+00
descriptionA Rust serialization and deserialization library for TXT record format using Serde
homepagehttps://github.com/erhany/serde-txtrecord
repositoryhttps://github.com/erhany/serde-txtrecord
max_upload_size
id1783085
size73,144
& (erhant)

documentation

https://docs.rs/serde-txtrecord

README

Serde TXT Record

A Rust serialization and deserialization library for TXT record format using Serde.

License: MIT Workflow: Tests MSRV

This library provides custom serde support for converting Rust data structures to and from TXT record format commonly used in DNS TXT records and configuration files.

  • Simple key-value pairs: key: valuekey=value
  • Arrays: key: ["val", "bal"]key_0=val, key_1=bal, key_len=2
  • Objects: key: { foo: "val", bar: "bal" }key.foo=val, key.bar=bal
  • Record length limits: Each key=value record can be limited to a maximum length (default: 255 characters)
  • Configurable separators and suffixes: Customize array separators, object separators, and array length suffixes
  • All Rust primitive types: Support for strings, numbers, booleans, options, and more

This library is particularly useful for:

  • DNS TXT Records: Storing structured configuration in DNS TXT records
  • Configuration Files: Simple key-value configuration format
  • Environment Variables: Flattening complex structures for environment variable storage
  • Log Structured Data: Converting structured data to searchable key-value pairs
  • API Parameters: Flattening nested objects for form-encoded or query parameters

Installation

Add this to your Cargo.toml:

[dependencies]
serde-txtrecord = "0.1.0"
serde = { version = "1.0", features = ["derive"] }

Usage

You can use the to_txt_records and from_txt_records functions on a struct that has the Serialize and Deserialize traits, respectively.

use serde::{Serialize, Deserialize};
use serde_txtrecord::{to_txt_records, from_txt_records};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Person {
    name: String,
    age: u32,
    active: bool,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let person = Person {
        name: "Alice".to_string(),
        age: 30,
        active: true,
    };

    // serialize to TXT records
    let records = to_txt_records(&person)?;
    // > name=Alice
    // > age=30
    // > active=true

    // Deserialize back from TXT records
    let deserialized: Person = from_txt_records(records)?;
    assert_eq!(person, deserialized);

    Ok(())
}

You can provide a custom configuration as well, to avoid clashing names; use with to_txt_records_with_config and from_txt_records_with_config.

use serde_txtrecord::{to_txt_records_with_config, TxtRecordConfig};

let config = TxtRecordConfig {
    array_separator: "-".to_string(),         // use "-" instead of "_" for arrays
    object_separator: "/".to_string(),        // use "/" instead of "." for objects
    record_len: 100,                          // limit records to 100 characters
    array_len_suffix: ".count".to_string(),   // use ".count" instead of "_len"
};

let data = vec!["item1", "item2", "item3"];
let records = to_txt_records_with_config(&data, config)?;
// 0-0=item1
// 0-1=item2
// 0-2=item3
// 0.count=3

Testing

Run the test suite:

cargo test

# run an example
cargo run --example complex

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under the MIT License.

Commit count: 0

cargo fmt