use std::fmt;
use terraform_registry::Address;
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TerraformSourceKind {
Module,
Provider,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TerraformSource {
pub kind: TerraformSourceKind,
pub address: String,
}
impl TerraformSource {
pub fn new_module(address: impl Into<String>) -> Self {
Self {
kind: TerraformSourceKind::Module,
address: address.into(),
}
}
pub fn new_provider(address: impl Into<String>) -> Self {
Self {
kind: TerraformSourceKind::Provider,
address: address.into(),
}
}
pub fn kind(&self) -> TerraformSourceKind {
self.kind
}
pub fn address(&self) -> &str {
&self.address
}
pub fn parse_address(&self) -> Result<Address, terraform_registry::Error> {
match self.kind {
TerraformSourceKind::Module => Address::parse_module(&self.address),
TerraformSourceKind::Provider => Address::parse_provider(&self.address),
}
}
pub fn describe(&self) -> String {
self.address.clone()
}
pub fn parse_url(url: &url::Url) -> Result<Self, crate::Error> {
let mut repository = url.clone();
repository.set_fragment(None);
let address = repository
.as_str()
.strip_prefix("terraform://")
.ok_or_else(|| {
crate::Error::invalid_source(url.clone(), "expected terraform://<MODULE ADDRESS>")
})?
.to_string();
Ok(Self {
kind: TerraformSourceKind::Module,
address,
})
}
}
impl fmt::Display for TerraformSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self.kind {
TerraformSourceKind::Module => "Terraform module",
TerraformSourceKind::Provider => "Terraform provider",
};
f.write_str(s)
}
}
#[derive(serde::Deserialize)]
pub(super) enum TerraformSourceSerialized {
Module(String),
Provider(String),
}
impl From<TerraformSourceSerialized> for TerraformSource {
fn from(value: TerraformSourceSerialized) -> Self {
let (kind, address) = match value {
TerraformSourceSerialized::Module(address) => (TerraformSourceKind::Module, address),
TerraformSourceSerialized::Provider(address) => {
(TerraformSourceKind::Provider, address)
}
};
Self { kind, address }
}
}