use std::sync::Arc;
use serde::{Deserialize, Serialize};
use typed_builder::TypedBuilder;
use crate::ir::{AccountId, Address, AttributeMap, Expression, ProviderRef, Region, Span};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum ResourceKind {
Managed,
Data,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum BlockKind {
Resource,
Data,
Module,
Provider,
Variable,
Locals,
Output,
Terraform,
Include,
Generate,
Dependency,
Inputs,
Unknown,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TypedBuilder)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(setter(into)))]
pub struct Resource {
pub address: Address,
pub kind: ResourceKind,
pub type_: Arc<str>,
pub name: Arc<str>,
#[builder(default)]
pub provider_ref: Option<ProviderRef>,
#[builder(default)]
pub count_expr: Option<Expression>,
#[builder(default)]
pub for_each_expr: Option<Expression>,
#[builder(default)]
pub depends_on: Vec<Address>,
#[builder(default)]
pub attributes: AttributeMap,
#[builder(default)]
pub account_id: Option<AccountId>,
#[builder(default)]
pub account_name: Option<Arc<str>>,
#[builder(default)]
pub region: Option<Region>,
pub span: Span,
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use std::sync::Arc;
use super::*;
use crate::ir::{Address, Span};
#[test]
fn test_should_build_minimal_resource() {
let r = Resource::builder()
.address(Address::new("aws_db_instance.x").unwrap())
.kind(ResourceKind::Managed)
.type_(Arc::<str>::from("aws_db_instance"))
.name(Arc::<str>::from("x"))
.span(Span::synthetic())
.build();
assert_eq!(r.address.as_str(), "aws_db_instance.x");
assert!(r.depends_on.is_empty());
assert!(r.attributes.is_empty());
assert!(r.provider_ref.is_none());
}
#[test]
fn test_should_serde_round_trip_resource() {
let r = Resource::builder()
.address(Address::new("aws_iam_role.r").unwrap())
.kind(ResourceKind::Managed)
.type_(Arc::<str>::from("aws_iam_role"))
.name(Arc::<str>::from("r"))
.span(Span::synthetic())
.build();
let json = serde_json::to_string(&r).unwrap();
let back: Resource = serde_json::from_str(&json).unwrap();
assert_eq!(r, back);
}
}