use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct PostmanEnvironment {
pub id: Option<String>,
pub name: Option<String>,
#[serde(default)]
pub values: Vec<EnvironmentValue>,
}
#[derive(Debug, Deserialize)]
pub struct EnvironmentValue {
pub key: String,
pub value: Option<String>,
pub description: Option<String>,
#[serde(default = "default_enabled")]
pub enabled: bool,
}
#[derive(Debug)]
pub struct EnvironmentImportResult {
pub name: String,
pub variables: HashMap<String, EnvironmentVariable>,
pub enabled_count: usize,
pub total_count: usize,
}
#[derive(Debug, Serialize, Clone)]
pub struct EnvironmentVariable {
pub value: String,
pub description: Option<String>,
pub enabled: bool,
pub source: VariableSource,
}
#[derive(Debug, Serialize, Clone)]
pub enum VariableSource {
Environment(String),
Collection,
}
fn default_enabled() -> bool {
true
}
pub fn import_postman_environment(content: &str) -> Result<EnvironmentImportResult, String> {
let environment: PostmanEnvironment = serde_json::from_str(content)
.map_err(|e| format!("Failed to parse Postman environment: {}", e))?;
let mut variables = HashMap::new();
let mut enabled_count = 0;
let mut total_count = 0;
let env_name = environment.name.unwrap_or_else(|| "Unnamed Environment".to_string());
for env_value in environment.values {
total_count += 1;
if env_value.enabled && env_value.value.is_some() {
enabled_count += 1;
let variable = EnvironmentVariable {
value: env_value.value.unwrap(),
description: env_value.description,
enabled: env_value.enabled,
source: VariableSource::Environment(env_name.clone()),
};
variables.insert(env_value.key, variable);
}
}
Ok(EnvironmentImportResult {
name: env_name,
variables,
enabled_count,
total_count,
})
}
pub fn is_postman_environment_json(content: &str) -> bool {
if let Ok(json) = serde_json::from_str::<serde_json::Value>(content) {
if let Some(obj) = json.as_object() {
let has_values = obj.contains_key("values");
let has_name_or_id = obj.contains_key("name") || obj.contains_key("id");
let values_is_array = if let Some(values) = obj.get("values") {
values.is_array()
} else {
false
};
if has_values && has_name_or_id && values_is_array {
if let Some(values_array) = obj.get("values") {
if let Some(arr) = values_array.as_array() {
if !arr.is_empty() {
if let Some(first_item) = arr.first() {
if let Some(item_obj) = first_item.as_object() {
let has_key = item_obj.contains_key("key");
let has_value = item_obj.contains_key("value")
|| item_obj.contains_key("enabled");
return has_key && has_value;
}
}
}
}
}
}
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_postman_environment() {
let env_json = r#"{
"id": "env-123",
"name": "Development Environment",
"values": [
{
"key": "base_url",
"value": "https://api.dev.example.com",
"description": "API base URL",
"enabled": true
},
{
"key": "api_key",
"value": "dev-key-123",
"enabled": true
},
{
"key": "disabled_var",
"value": "should_not_import",
"enabled": false
}
]
}"#;
let result = import_postman_environment(env_json).unwrap();
assert_eq!(result.name, "Development Environment");
assert_eq!(result.total_count, 3);
assert_eq!(result.enabled_count, 2);
assert_eq!(result.variables.len(), 2);
let base_url_var = result.variables.get("base_url").unwrap();
assert_eq!(base_url_var.value, "https://api.dev.example.com");
assert_eq!(base_url_var.description.as_ref().unwrap(), "API base URL");
assert!(base_url_var.enabled);
let api_key_var = result.variables.get("api_key").unwrap();
assert_eq!(api_key_var.value, "dev-key-123");
assert!(api_key_var.enabled);
}
#[test]
fn test_detect_postman_environment() {
let env_json = r#"{
"id": "env-123",
"name": "Test Environment",
"values": [
{
"key": "test_var",
"value": "test_value",
"enabled": true
}
]
}"#;
assert!(is_postman_environment_json(env_json));
let not_env_json = r#"{
"info": {
"name": "Test Collection"
},
"item": []
}"#;
assert!(!is_postman_environment_json(not_env_json));
}
#[test]
fn test_parse_minimal_environment() {
let minimal_env_json = r#"{
"values": [
{
"key": "minimal_var",
"value": "minimal_value",
"enabled": true
}
]
}"#;
let result = import_postman_environment(minimal_env_json).unwrap();
assert_eq!(result.name, "Unnamed Environment");
assert_eq!(result.total_count, 1);
assert_eq!(result.enabled_count, 1);
assert_eq!(result.variables.len(), 1);
}
}