monosecret 0.4.1

Declarative secrets, every environment, any provider
Documentation
use std::fmt;
use std::str::FromStr;

use serde::Deserialize;
use serde::Serialize;

use crate::MonosecretError;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum SopsFormat {
	#[default]
	Yaml,
	Json,
	Env,
	Ini,
}

impl fmt::Display for SopsFormat {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		match self {
			Self::Yaml => write!(f, "yaml"),
			Self::Json => write!(f, "json"),
			Self::Env => write!(f, "env"),
			Self::Ini => write!(f, "ini"),
		}
	}
}

impl SopsFormat {
	/// The spelling accepted by SOPS' `--input-type` flag. SOPS can infer INI
	/// only from a `.ini` filename and does not expose an `ini` input type.
	pub fn sops_input_type(self) -> Option<&'static str> {
		match self {
			Self::Yaml => Some("yaml"),
			Self::Json => Some("json"),
			Self::Env => Some("dotenv"),
			Self::Ini => None,
		}
	}
}

impl FromStr for SopsFormat {
	type Err = MonosecretError;

	fn from_str(s: &str) -> Result<Self, Self::Err> {
		match s.to_lowercase().as_str() {
			"yaml" | "yml" => Ok(Self::Yaml),
			"json" => Ok(Self::Json),
			"env" | "dotenv" => Ok(Self::Env),
			"ini" => Ok(Self::Ini),
			_ => {
				Err(MonosecretError::ProviderOperationFailed(format!(
					"Unsupported SOPS format: {s}. Supported formats: yaml, json, env, ini"
				)))
			}
		}
	}
}

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn test_sops_format_from_str() {
		assert_eq!(SopsFormat::from_str("yaml").unwrap(), SopsFormat::Yaml);
		assert_eq!(SopsFormat::from_str("yml").unwrap(), SopsFormat::Yaml);
		assert_eq!(SopsFormat::from_str("json").unwrap(), SopsFormat::Json);
		assert_eq!(SopsFormat::from_str("env").unwrap(), SopsFormat::Env);
		assert_eq!(SopsFormat::from_str("dotenv").unwrap(), SopsFormat::Env);
		assert_eq!(SopsFormat::from_str("ini").unwrap(), SopsFormat::Ini);

		assert!(SopsFormat::from_str("unknown").is_err());
	}
}