Expand description

Miniconf

Miniconf is a a lightweight utility to manage run-time configurable settings. It allows access and manipulation of struct fields by assigning each field a unique path-like identifier.

Overview

Miniconf uses a Derive macro to automatically assign unique paths to each setting. All values are transmitted and received in JSON format.

With the derive macro, field values can be easily retrieved or modified using a run-time string.

Supported Protocols

Miniconf is designed to be protocol-agnostic. Any means that you have of receiving input from some external source can be used to acquire paths and values for updating settings.

There is also an MQTT-based client provided to manage settings via the MQTT protocol and JSON.

Example

use miniconf::{Miniconf, MiniconfAtomic};
use serde::{Serialize, Deserialize};

#[derive(Deserialize, Serialize, MiniconfAtomic, Default)]
struct Coefficients {
    forward: f32,
    backward: f32,
}

#[derive(Miniconf, Default)]
struct Settings {
    filter: Coefficients,
    channel_gain: [f32; 2],
    sample_rate: u32,
    force_update: bool,
}

let mut settings = Settings::default();

// Update sample rate.
settings.set("sample_rate", b"350").unwrap();

// Update filter coefficients.
settings.set("filter", b"{\"forward\": 35.6, \"backward\": 0.0}").unwrap();

// Update channel gain for channel 0.
settings.set("channel_gain/0", b"15").unwrap();

// Serialize the current sample rate into the provided buffer.
let mut buffer = [0u8; 256];
let len = settings.get("sample_rate", &mut buffer).unwrap();

assert_eq!(&buffer[..len], b"350");

Features

Miniconf supports an MQTT-based client for configuring and managing run-time settings via MQTT. To enable this feature, enable the mqtt-client feature.

#[derive(miniconf::Miniconf, Default, Clone, Debug)]
struct Settings {
    forward: f32,
}

// Construct the MQTT client.
let mut client: miniconf::MqttClient<_, _, _, 256> = miniconf::MqttClient::new(
    std_embedded_nal::Stack::default(),
    "example-device",
    "quartiq/miniconf-sample",
    "127.0.0.1".parse().unwrap(),
    std_embedded_time::StandardClock::default(),
    Settings::default(),
)
.unwrap();

loop {
    // Continually process client updates to detect settings changes.
    if client.update().unwrap() {
        println!("Settings updated: {:?}", client.settings());
    }
}

Path iteration

Miniconf also allows iteration over all settings paths:

use miniconf::Miniconf;

#[derive(Default, Miniconf)]
struct Settings {
    sample_rate: u32,
    update: bool,
}

let settings = Settings::default();

let mut state = [0; 8];
for topic in settings.iter::<128>(&mut state).unwrap() {
    println!("Discovered topic: `{:?}`", topic);
}

Limitations

Minconf cannot be used with some of Rust’s more complex types. Some unsupported types:

  • Complex enums
  • Tuples

Re-exports

pub use minimq;
pub use minimq::embedded_time;
pub use heapless;

Modules

Provides iteration utilities over Miniconf structures.

Structs

Metadata about a settings structure.

MQTT settings interface.

Enums

Errors that occur during settings configuration

Errors that occur during iteration over topic paths.

Traits

Derive-able trait for structures that can be mutated using serialized paths and values.

Derive Macros

Derive the Miniconf trait for custom types.

Derive the Miniconf trait for a custom type that must be updated atomically.