Miniconf
Miniconf enables lightweight (no_std) partial serialization (retrieval) and deserialization
(updates, modification) within a hierarchical namespace by path. The namespace is backed by
structs and arrays of serializable types.
Miniconf can be used as a very simple and flexible backend for run-time settings management in embedded devices over any transport. It was originally designed to work with JSON (serde_json_core) payloads over MQTT (minimq) and provides a comlete MQTT settings management client and a Python reference implementation to ineract with it.
Example
use Miniconf;
use ;
let mut settings = default;
let mut buf = ;
// Atomic updates by field name
settings.set?;
assert_eq!;
settings.set?;
settings.set?;
settings.set?;
settings.set?;
settings.set?;
// Deep access by field name in a struct
settings.set?;
// ... or by index in an array
settings.set?;
// ... or by index and then struct field name
settings.set?;
// If a deferred Option is `None` it is hidden at runtime
settings.set.unwrap_err;
settings.option_defer = Some;
settings.set?;
settings.set.unwrap_err;
*settings.option_miniconf = Some;
settings.set?;
// Serializing an element by path
let len = settings.get?;
assert_eq!;
// Iterating over all elements
for path in .unwrap
# Ok::
MQTT
There is an MQTT-based client that implements settings management over the MQTT protocol with JSON payloads. A Python reference library is provided that interfaces with it.
# Discover the complete unique prefix of an application listening to messages
# under the topic `quartiq/application/12345` and set its `foo` setting to `true`.
Design
For structs with named fields, Miniconf offers a derive macro to automatically assign a unique path to each item in the namespace of the struct. The macro implements the [Miniconf] trait that exposes access to serialized field values through their path. All types supported by [serde_json_core] can be used as fields.
Elements of homogeneous [core::array]s are similarly accessed through their numeric indices.
Structs, arrays, and Options can then be cascaded to construct a multi-level namespace.
Namespace depth and access to individual elements instead of the atomic updates
is configured at compile (derive) time using the #[miniconf(defer)] attribute.
Option is used with #[miniconf(defer)] to support paths that may be absent (masked) at
runtime.
While the [Miniconf] implementations for [core::array] and [core::option::Option] by provide atomic access to their respective inner element(s), [Array] and [Option] have alternative [Miniconf] implementations that expose deep access into the inner element(s) through their respective inner [Miniconf] implementations.
Formats
The path hierarchy separator is the slash /.
Values are serialized into and deserialized from JSON.
Transport
Miniconf is designed to be protocol-agnostic. Any means that can receive key-value input from some external source can be used to modify values by path.
Limitations
Deferred (non-atomic) access to inner elements of some types is not yet supported. This includes:
- Complex enums (other than [core::option::Option])
- Tuple structs (other than [Option], [Array])
Features
mqtt-clientEnabled the MQTT client feature. See the example in [MqttClient].