This crate aims to compile schemas extracted from Terraform into Serde type definitions.
A Terraform schema is required for generating the Rust types responsible of deserialization and serialization from Rust. It can either be exported from your Terraform plan or manually generated. We'll take the latter approach, defining an reference schema with just one provider type, exposing just one attribute :
json
{
"provider_schemas" : {
"test_provider" : {
"provider" : {
"version" : 0,
"block" : {
"attributes" : {
"base_url" : {
"type" : "string",
"description" : "The url.",
"optional" : true
}
}
}
},
"format_version" : "0.1"
}
In addition to a Rust library, this crate provides a binary tool tf-schemabindgen
to process Terraform schemas
saved on disk.
Outside of this repository, you may install the tool with:
bash
cargo install tf-schemabindgen
Then use $HOME/.cargo/bin/tfschema-bindgen
.
We're going to use this tool assuming that we're inside the repository.
The following command will generate Rust class definitions from the previous definitions written in the 'test.json' file and write them into test.rs
:
bash
cargo run --bin tfschema-bindgen -- test.json > test.rs
This is how the generated Rust definitions followed by how these can be consumed for parsing a Terraform configuration descriptor :
```rust
use std::collections::BTreeMap as Map; use serde::{Serialize, Deserialize}; use serde_bytes::ByteBuf as Bytes;
pub struct config {
pub datasource: Option
pub enum datasource_root { }
pub enum providerroot {
testprovider(Box
pub enum resource_root { }
pub struct testproviderdetails {
pub base_url: Option
const TFJSONCONFIG: &str = r#"{ "provider": [ { "testprovider": [ { "baseurl": "https://acme.com/foo" } ] } ] }"#;
fn main() -> Result<(), std::io::Error> { let res: config = serdejson::fromstr(TFJSONCONFIG).unwrap();
asserteq!(res.provider.asref().map(|x| x.isempty()), Some(false)); asserteq!( res.provider.asref().map(|x| x.get(0).isnone()), Some(false) ); let prv = res .provider .asref() .andthen(|x| x.get(0)) .andthen(|x| match x { providerroot::testprovider(p) => p.get(0), }); asserteq!(prv.isnone(), false); asserteq!( prv.andthen(|x| x.baseurl.toowned()), Some("https://acme.com/foo".toowned()) ); print!("success!\n"); Ok(()) } ```
In addition to a Rust library and generation tool, this crate provides the above example which can be executed using the following command :
bash
cargo run --example quickstart
This project is available under the terms of either the Apache 2.0 license or the MIT license.