tf_bindgen/model/
config.rs1use std::collections::HashMap;
2
3use semver::{Comparator, Op, VersionReq};
4use serde::{Deserialize, Serialize};
5
6#[derive(Default, Debug, Deserialize, Serialize)]
7pub struct Terraform {
8 required_providers: HashMap<String, Provider>,
9}
10
11#[derive(Debug, Deserialize, Serialize)]
12pub struct Provider {
13 source: String,
14 version: String,
15}
16
17impl Terraform {
18 pub fn add_provider(&mut self, provider_name: &str, constraint: VersionReq) {
20 let segments: Vec<_> = provider_name.split('/').collect();
21 let name = segments.last().unwrap();
22 let provider = Provider {
23 source: if segments.len() == 2 {
24 provider_name.to_string()
25 } else {
26 format!("hashicorp/{}", name)
27 },
28 version: constraint
29 .comparators
30 .into_iter()
31 .map(cargo_simplify_version)
32 .fold(String::from(">=0.0.0"), |text, constraint| {
33 text + "," + &constraint
34 }),
35 };
36 self.required_providers.insert(name.to_string(), provider);
37 }
38
39 pub fn provider(&self) -> impl Iterator<Item = (&String, &Provider)> {
41 self.required_providers.iter()
42 }
43}
44
45fn cargo_simplify_version(constraint: Comparator) -> String {
46 let major = constraint.major;
47 let minor = constraint.minor.unwrap_or(0);
48 let patch = constraint.patch.unwrap_or(0);
49 assert!(
50 constraint.pre.is_empty(),
51 "pre release constraints are not supported"
52 );
53 match constraint.op {
54 Op::Tilde if constraint.minor.is_some() => {
55 format!(">={major}{minor}{patch},<{major}{}.0", minor + 1)
56 }
57 Op::Caret if major == 0 && constraint.minor.is_none() => ">=0.0.0,<1.0.0".to_string(),
58 Op::Caret if major == 0 && minor == 0 && constraint.patch.is_some() => {
59 format!(">=0.0.{patch},<0.0.{}", patch + 1)
60 }
61 Op::Caret if major == 0 => {
62 format!(">=0.{minor}.0,<0.{}.0", minor + 1)
63 }
64 Op::Wildcard if constraint.minor.is_some() => {
65 format!(">={major}.{minor}.0,<{major}.{}.0", minor + 1)
66 }
67 Op::Tilde | Op::Caret | Op::Wildcard => {
68 format!(">={major}.{minor}.{patch},<{}.0.0", major + 1)
69 }
70 Op::Exact => format!("={major}.{minor}.{patch}"),
71 Op::Greater => format!(">{major}.{minor}.{patch}"),
72 Op::GreaterEq => format!(">={major}.{minor}.{patch}"),
73 Op::Less => format!("<{major}.{minor}.{patch}"),
74 Op::LessEq => format!("<={major}.{minor}.{patch}"),
75 _ => unimplemented!(),
76 }
77}