hcl/structure/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
//! Types to represent the HCL structural sub-language.
//!
//! The main types in this module are:
//!
//! - [`Attribute`]: represent an HCL attribute
//! - [`Block`]: represent an HCL block
//! - [`BlockBuilder`]: provides functionality for building `Block`s
//! - [`Body`]: represent the body of an HCL configuration or block
//! - [`BodyBuilder`]: provides functionality for building `Body`s
//!
//! ## Examples
//!
//! Building HCL structures:
//!
//! ```
//! use hcl::{Body, Block, BlockLabel};
//!
//! let body = Body::builder()
//! .add_block(
//! Block::builder("resource")
//! .add_label("aws_s3_bucket")
//! .add_label("mybucket")
//! .add_attribute(("name", "mybucket"))
//! .add_block(
//! Block::builder("logging")
//! .add_attribute(("target_bucket", "mylogsbucket"))
//! .build()
//! )
//! .build()
//! )
//! .build();
//!
//! let mut iter = body.attributes();
//!
//! assert_eq!(iter.next(), None);
//!
//! let mut iter = body.blocks();
//!
//! let block = iter.next().unwrap();
//!
//! assert_eq!(block.identifier(), "resource");
//! assert_eq!(
//! block.labels().first(),
//! Some(&BlockLabel::from("aws_s3_bucket")),
//! );
//! ```
mod attribute;
mod block;
mod body;
pub(crate) mod de;
mod edit;
pub mod iter;
mod json_spec;
mod ser;
#[cfg(test)]
mod tests;
pub(crate) use self::json_spec::IntoJsonSpec;
pub use self::{
attribute::Attribute,
block::{Block, BlockBuilder, BlockLabel},
body::{Body, BodyBuilder},
};
use crate::Value;
use serde::Deserialize;
/// Represents an HCL structure.
///
/// There are two possible structures that can occur in an HCL [`Body`]: [`Attribute`]s and [`Block`]s.
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum Structure {
/// Represents an HCL attribute.
Attribute(Attribute),
/// Represents an HCL block.
Block(Block),
}
impl Structure {
/// Returns `true` if the structure represents an [`Attribute`].
pub fn is_attribute(&self) -> bool {
self.as_attribute().is_some()
}
/// Returns `true` if the structure represents a [`Block`].
pub fn is_block(&self) -> bool {
self.as_block().is_some()
}
/// Takes ownership of the `Structure` and, if it is an `Attribute`, returns its value,
/// otherwise `None`.
pub fn into_attribute(self) -> Option<Attribute> {
match self {
Structure::Attribute(attr) => Some(attr),
Structure::Block(_) => None,
}
}
/// If the `Structure` is an `Attribute`, returns a reference to it, otherwise `None`.
pub fn as_attribute(&self) -> Option<&Attribute> {
match self {
Structure::Attribute(attr) => Some(attr),
Structure::Block(_) => None,
}
}
/// If the `Structure` is an `Attribute`, returns a mutable reference to it, otherwise `None`.
pub fn as_attribute_mut(&mut self) -> Option<&mut Attribute> {
match self {
Structure::Attribute(attr) => Some(attr),
Structure::Block(_) => None,
}
}
/// Takes ownership of the `Structure` and, if it is a `Block`, returns its value,
/// otherwise `None`.
pub fn into_block(self) -> Option<Block> {
match self {
Structure::Block(block) => Some(block),
Structure::Attribute(_) => None,
}
}
/// If the `Structure` is a `Block`, returns a reference to it, otherwise `None`.
pub fn as_block(&self) -> Option<&Block> {
match self {
Structure::Block(block) => Some(block),
Structure::Attribute(_) => None,
}
}
/// If the `Structure` is a `Block`, returns a mutable reference to it, otherwise `None`.
pub fn as_block_mut(&mut self) -> Option<&mut Block> {
match self {
Structure::Block(block) => Some(block),
Structure::Attribute(_) => None,
}
}
}
impl From<Structure> for Value {
fn from(s: Structure) -> Value {
match s {
Structure::Attribute(attr) => attr.into(),
Structure::Block(block) => block.into(),
}
}
}
impl From<Attribute> for Structure {
fn from(attr: Attribute) -> Structure {
Structure::Attribute(attr)
}
}
impl From<Block> for Structure {
fn from(block: Block) -> Structure {
Structure::Block(block)
}
}