tanzim-value 0.11.0

Located configuration values
Documentation

tanzim-value

Package | Documentation | Repository

Foundational value types for the tanzim pipeline.

Types

  • [Value] — Bool, Int, Float, String, List, Map, Null
  • [LocatedValue] — Value + [Location] (full originating [tanzim_source::Source], optional 1-based line/column)
  • [Map] — ordered Vec-backed map; last inserted key wins on lookup
  • [Error] — parse-time and (with the serde feature) deserialize errors; use {error:#} for a source snippet with caret underline

Location

[Location] holds the full originating [tanzim_source::Source] (name, options, resource, including any on_error policy) so any value or error can be traced back to how it was declared. Positions (line, column, length) are 1-based and stored as Option<NonZeroU32>. [Error] boxes its [Location] field so results stay small enough to return by value without tripping clippy::result_large_err. Construct via [Location::in_source] (real source) or [Location::at] (bare name/resource for synthetic origins); neither exposes NonZeroU32 to callers.

Example

use tanzim_value::{Value, LocatedValue, Location, Map};

let mut map = Map::new();
let location = Location::at("env", "", None, None, None);
map.insert(
    "port".to_string(),
    LocatedValue::new(Value::Int(8080), location.clone()),
);
map.insert(
    "host".to_string(),
    LocatedValue::new(Value::String("localhost".to_string()), location),
);
assert!(map.contains_key("port"));
assert_eq!(map.len(), 2);

Deserializing into your own types (serde feature)

With the optional serde feature, [Value] and [LocatedValue] implement serde::Deserializer, so a config tree turns straight into your own structs. A [LocatedValue] runs the same [Value] deserializer but, on failure, stamps the offending node's [Location] onto the error:

# // Deserialization lives behind the `serde` feature.
# #[cfg(feature = "serde")]
# {
use serde::Deserialize;
use tanzim_value::{Value, LocatedValue, Location, Map};

#[derive(Deserialize)]
struct Server {
    host: String,
    port: u16,
}

# let location = Location::at("file", "server.json", None, None, None);
# let mut map = Map::new();
# map.insert(
#     "host".to_string(),
#     LocatedValue::new(Value::String("localhost".to_string()), location.clone()),
# );
# map.insert(
#     "port".to_string(),
#     LocatedValue::new(Value::Int(8080), location.clone()),
# );
# let tree = LocatedValue::new(Value::Map(map), location);
// `tree` is a `LocatedValue` a parser would produce, here the map
// `{ host: "localhost", port: 8080 }` located at `server.json`.
let server: Server = tree.try_deserialize().unwrap();
assert_eq!(server.host, "localhost");
assert_eq!(server.port, 8080);
// On a type mismatch: `Err(Error::Deserialize { .. })` whose `Display` points at
// `source:resource:line:column`.
# }

Features

Feature Enables
serde serde::Deserializer for [Value]/[LocatedValue] + try_deserialize::<T>(), and serde::de::Error for [Error]

Off by default.

Relations

  • Used by all other tanzim crates.
  • tanzim-parse produces LocatedValue trees from raw bytes.
  • tanzim-merge consumes LocatedValue trees to produce merged maps.