tfschema_bindgen/
lib.rs

1//! This crate aims to compile schemas extracted from Terraform providers into Serde type definitions.
2//!
3//! ## Quick Start
4//!
5//! A Terraform schema is required for generating Rust types responsible of deserialization and serialization.   
6//! It can either be exported from your Terraform configuration or manually generated.
7//! We'll take the latter approach, therefore defining a reference schema with just one provider type having one attribute:
8//!
9//! ```json
10//!{
11//!    "provider_schemas": {
12//!        "test_provider": {
13//!            "provider": {
14//!                "version": 0,
15//!                "block": {
16//!                    "attributes": {
17//!                        "base_url": {
18//!                            "type": "string",
19//!                            "description": "The url.",
20//!                            "optional": true
21//!                        }
22//!                    }
23//!                }
24//!            }
25//!        }
26//!    },
27//!    "format_version": "0.1"
28//!}
29//! ```
30//!
31//! In addition to a Rust library, this crate provides a binary tool `tfbindgen` to process Terraform schemas
32//! saved on disk.
33//! Outside of this repository, you may install the tool with:
34//!
35//! ```bash
36//! cargo install tfschema-bindgen
37//! ```
38//!
39//! Then use `$HOME/.cargo/bin/tfbindgen`.
40//!
41//! We're going to use this tool assuming that we're inside the repository.
42//!
43//! The following command will generate Serde bindings from the previous definitions, outputting those to `test.rs` module:
44//!
45//! ```bash
46//! cargo run --bin tfbindgen -- test.json > test.rs
47//! ```
48//!
49//! The following is a Rust example snippet comprising the previously generated bindings and a main function building on these in order
50//! deserialize a configuration descriptor adhering to our Terraform schema:
51//!
52//! ```
53//! #![allow(unused_imports, non_snake_case, non_camel_case_types, non_upper_case_globals)]
54//! use std::collections::BTreeMap as Map;
55//! use serde::{Serialize, Deserialize};
56//! use serde_bytes::ByteBuf as Bytes;
57//!
58//! #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize, Default)]
59//! pub struct config {
60//!     #[serde(skip_serializing_if = "Option::is_none")]
61//!     pub data: Option<Vec<data_root>>,
62//!     #[serde(skip_serializing_if = "Option::is_none")]
63//!     pub provider: Option<Vec<provider_root>>,
64//!     #[serde(skip_serializing_if = "Option::is_none")]
65//!     pub resource: Option<Vec<resource_root>>,
66//! }
67//!
68//! #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
69//! pub enum data_root {
70//! }
71//!
72//! #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
73//! pub enum provider_root {
74//!     test_provider(Vec<test_provider_details>),
75//! }
76//!
77//! #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
78//! pub enum resource_root {
79//! }
80//!
81//! #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize, Default)]
82//! pub struct test_provider_details {
83//!     #[serde(skip_serializing_if = "Option::is_none")]
84//!     pub base_url: Option<String>,
85//! }
86//!
87//! const TF_JSON_CONFIG: &str = r#"{
88//!    "provider": [
89//!      {
90//!        "test_provider": [
91//!          {
92//!            "base_url": "https://acme.com/foo"
93//!          }
94//!        ]
95//!      }
96//!    ]
97//! }"#;
98//!
99//! fn main() -> Result<(), std::io::Error> {
100//!    let res: config = serde_json::from_str(TF_JSON_CONFIG).unwrap();
101//!
102//!    assert_eq!(res.provider.as_ref().map(|x| x.is_empty()), Some(false));
103//!    assert_eq!(
104//!        res.provider.as_ref().map(|x| x.get(0).is_none()),
105//!        Some(false)
106//!    );
107//!    let prv = res
108//!        .provider
109//!        .as_ref()
110//!        .and_then(|x| x.get(0))
111//!        .and_then(|x| match x {
112//!            provider_root::test_provider(p) => p.get(0),
113//!        });
114//!    assert_eq!(prv.is_none(), false);
115//!    assert_eq!(
116//!        prv.and_then(|x| x.base_url.to_owned()),
117//!        Some("https://acme.com/foo".to_owned())
118//!    );
119//!    print!("success!\n");
120//!    Ok(())
121//! }
122//! ```
123//! ## Quickstart Example
124//!
125//! In addition to a Rust library and generation tool, this crate provides the above example which
126//! can be executed using the following command:
127//!
128//! ```bash
129//! cargo run --example quickstart
130//! ```
131//!
132//! ## Consuming third-party Terraform schemas
133//!
134//! In order to operate on Terraform configuration descriptors of third-party providers, Rust bindings have to be generated using the
135//! provided schema descriptor in the JSON format.
136//!   
137//! Firstly, create a minimal Terraform configuration declaring the target provider. The following is an example for enabling
138//! the Amazon Web Services (AWS) Terraform provider:
139//!
140//! ```code
141//! provider "aws" {
142//!  version = ">= 2.31.0, < 3.0"
143//!}
144//! ```
145//!
146//! Initialize Terraform so that configured providers are installed in the local environment:
147//!
148//! ```bash
149//! terraform init
150//! ```
151//!
152//! Secondly, extract the schema for the providers defined in the Terraform configuration, AWS in this case:
153//!
154//! ```bash
155//! terraform providers schema -json > aws-provider-schema.json
156//! ```
157//!
158//! Finally, generate the Rust (de)serialization types for the given provider using the following command (assuming you are inside the repository):
159//!
160//! ```bash
161//! cargo run --bin tfbindgen -- aws-provider-schema.json > aws_provider_schema.rs
162//! ```
163//!
164//! In order do (de)serialize provider's configuration, import the generated module in your application.
165//!
166
167// registry creation
168pub mod binding;
169
170// code generator
171pub mod emit;
172
173// configuraiton support for code generation
174pub mod config;
175
176/// Utility functions to help testing code generators.
177#[doc(hidden)]
178pub mod test_utils;