Struct hcl::ser::LabeledBlock

source ·
pub struct LabeledBlock<T>(_);
Expand description

A transparent wrapper type which hints the Serializer to serialize T as a labeled HCL block.

When passed to a serializer other than the one from this crate, a LabeledBlock<T> serializes exactly like T, if T implements serde::Serialize.

A LabeledBlock<T> can only be used in the value position of a map-like structure. For example:

  • It can be used to wrap the value type of a map, e.g. Map<K, LabeledBlock<T>>
  • As the value of a struct field, e.g. struct S { field: LabeledBlock<T> }
  • Or as the value of an enum variant, e.g. enum E { Variant(LabeledBlock<T>) }

The serialized block’s identifier will be the respective map key, struct field name or variant name.

The wrapped T must be shaped as follows to be serialized as a labeled HCL block:

  • A map-like value (e.g. a map or struct) where the value may to be another LabeledBlock<T>, in which case a block with multiple labels is produced. Can be nested arbitrarily deep to allow for any number of block labels.
  • A sequence-like value (e.g. a vector, slice or tuple) with map-like elements as described above. In this case, multiple blocks with the same identifier and labels are produced.

Wrapping a type T that does not fulfil one of the criteria above in a LabeledBlock<T> will result in serialization errors.

For more convenient usage, see the labeled_block and doubly_labeled_block functions.

Example

use hcl::ser::LabeledBlock;
use indexmap::{indexmap, IndexMap};
use serde::Serialize;

#[derive(Serialize)]
struct Config {
    user: LabeledBlock<IndexMap<String, User>>,
}

#[derive(Serialize)]
struct User {
    email: String,
}

let users = indexmap! {
    "john".into() => User {
        email: "johndoe@example.com".into(),
    },
    "jane".into() => User {
        email: "janedoe@example.com".into(),
    },
};

let config = Config {
    user: LabeledBlock::new(users),
};

let expected = r#"
user "john" {
  email = "johndoe@example.com"
}

user "jane" {
  email = "janedoe@example.com"
}
"#.trim_start();

assert_eq!(hcl::to_string(&config)?, expected);

Implementations§

Create a new LabeledBlock<T> from a T.

Consume the LabeledBlock and return the wrapped T.

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Mutably dereferences the value.
Deserialize this value from the given Serde deserializer. Read more
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.