use crate::error::ApiError;
use crate::types::SalesforceId;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<SalesforceId>,
pub success: bool,
#[serde(default)]
pub errors: Vec<ApiError>,
}
impl CreateResponse {
#[must_use]
pub fn success(id: SalesforceId) -> Self {
Self {
id: Some(id),
success: true,
errors: Vec::new(),
}
}
#[must_use]
pub fn failure(errors: Vec<ApiError>) -> Self {
Self {
id: None,
success: false,
errors,
}
}
#[must_use]
pub const fn is_success(&self) -> bool {
self.success
}
#[must_use]
pub const fn is_failure(&self) -> bool {
!self.success
}
}
macro_rules! define_simple_response {
($(#[$meta:meta])* $name:ident) => {
$(#[$meta])*
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct $name {
/// Whether the operation succeeded.
pub success: bool,
#[serde(default)]
pub errors: Vec<ApiError>,
}
impl $name {
#[must_use]
pub const fn success() -> Self {
Self {
success: true,
errors: Vec::new(),
}
}
#[must_use]
pub fn failure(errors: Vec<ApiError>) -> Self {
Self {
success: false,
errors,
}
}
#[must_use]
pub const fn is_success(&self) -> bool {
self.success
}
#[must_use]
pub const fn is_failure(&self) -> bool {
!self.success
}
}
};
}
define_simple_response!(
UpdateResponse
);
define_simple_response!(
DeleteResponse
);
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpsertResponse {
pub id: SalesforceId,
pub success: bool,
pub created: bool,
#[serde(default)]
pub errors: Vec<ApiError>,
}
impl UpsertResponse {
#[must_use]
pub const fn created(id: SalesforceId) -> Self {
Self {
id,
success: true,
created: true,
errors: Vec::new(),
}
}
#[must_use]
pub const fn updated(id: SalesforceId) -> Self {
Self {
id,
success: true,
created: false,
errors: Vec::new(),
}
}
#[must_use]
pub fn failure(id: SalesforceId, errors: Vec<ApiError>) -> Self {
Self {
id,
success: false,
created: false,
errors,
}
}
#[must_use]
pub const fn is_success(&self) -> bool {
self.success
}
#[must_use]
pub const fn is_failure(&self) -> bool {
!self.success
}
#[must_use]
pub const fn is_created(&self) -> bool {
self.created
}
#[must_use]
pub const fn is_updated(&self) -> bool {
!self.created
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_support::Must;
#[test]
fn test_create_response_success() {
let id = SalesforceId::new("001000000000001AAA").must();
let response = CreateResponse::success(id.clone());
assert!(response.is_success());
assert!(!response.is_failure());
assert_eq!(response.id, Some(id));
assert!(response.errors.is_empty());
}
#[test]
fn test_create_response_failure() {
let errors = vec![ApiError::new("Test error", "TEST_ERROR")];
let response = CreateResponse::failure(errors.clone());
assert!(!response.is_success());
assert!(response.is_failure());
assert_eq!(response.id, None);
assert_eq!(response.errors, errors);
}
#[test]
fn test_create_response_serialize() {
let id = SalesforceId::new("001000000000001AAA").must();
let response = CreateResponse::success(id);
let json = serde_json::to_string(&response).must();
assert!(json.contains("\"success\":true"));
assert!(json.contains("001000000000001AAA"));
}
#[test]
fn test_create_response_deserialize() {
let json = r#"{
"id": "001000000000001AAA",
"success": true,
"errors": []
}"#;
let response: CreateResponse = serde_json::from_str(json).must();
assert!(response.is_success());
assert!(response.id.is_some());
}
#[test]
fn test_update_response_success() {
let response = UpdateResponse::success();
assert!(response.is_success());
assert!(!response.is_failure());
assert!(response.errors.is_empty());
}
#[test]
fn test_update_response_failure() {
let errors = vec![ApiError::new("Update failed", "UPDATE_ERROR")];
let response = UpdateResponse::failure(errors.clone());
assert!(!response.is_success());
assert!(response.is_failure());
assert_eq!(response.errors, errors);
}
#[test]
fn test_delete_response_success() {
let response = DeleteResponse::success();
assert!(response.is_success());
assert!(!response.is_failure());
assert!(response.errors.is_empty());
}
#[test]
fn test_delete_response_failure() {
let errors = vec![ApiError::new("Delete failed", "DELETE_ERROR")];
let response = DeleteResponse::failure(errors.clone());
assert!(!response.is_success());
assert!(response.is_failure());
assert_eq!(response.errors, errors);
}
#[test]
fn test_upsert_response_created() {
let id = SalesforceId::new("001000000000001AAA").must();
let response = UpsertResponse::created(id.clone());
assert!(response.is_success());
assert!(response.is_created());
assert!(!response.is_updated());
assert_eq!(response.id, id);
assert!(response.errors.is_empty());
}
#[test]
fn test_upsert_response_updated() {
let id = SalesforceId::new("001000000000001AAA").must();
let response = UpsertResponse::updated(id.clone());
assert!(response.is_success());
assert!(!response.is_created());
assert!(response.is_updated());
assert_eq!(response.id, id);
assert!(response.errors.is_empty());
}
#[test]
fn test_upsert_response_failure() {
let id = SalesforceId::new("001000000000001AAA").must();
let errors = vec![ApiError::new("Upsert failed", "UPSERT_ERROR")];
let response = UpsertResponse::failure(id.clone(), errors.clone());
assert!(!response.is_success());
assert!(response.is_failure());
assert_eq!(response.id, id);
assert_eq!(response.errors, errors);
}
#[test]
fn test_api_error_new() {
let error = ApiError::new("Test message", "TEST_CODE");
assert_eq!(error.message, "Test message");
assert_eq!(error.error_code, "TEST_CODE");
assert!(error.fields.is_empty());
}
#[test]
fn test_api_error_with_fields() {
let fields = vec!["Name".to_string(), "Email".to_string()];
let error =
ApiError::with_fields("Missing fields", "REQUIRED_FIELD_MISSING", fields.clone());
assert_eq!(error.message, "Missing fields");
assert_eq!(error.error_code, "REQUIRED_FIELD_MISSING");
assert_eq!(error.fields, fields);
}
#[test]
fn test_api_error_serialize() {
let error = ApiError::with_fields(
"Required fields missing",
"REQUIRED_FIELD_MISSING",
vec!["Name".to_string()],
);
let json = serde_json::to_string(&error).must();
assert!(json.contains("\"errorCode\":\"REQUIRED_FIELD_MISSING\""));
assert!(json.contains("\"message\":\"Required fields missing\""));
assert!(json.contains("\"fields\""));
}
#[test]
fn test_api_error_deserialize() {
let json = r#"{
"message": "Required fields are missing: [Name]",
"statusCode": "REQUIRED_FIELD_MISSING",
"fields": ["Name"]
}"#;
let error: ApiError = serde_json::from_str(json).must();
assert_eq!(error.error_code, "REQUIRED_FIELD_MISSING");
assert_eq!(error.fields, vec!["Name"]);
}
#[test]
fn test_response_roundtrip_serialization() {
let id = SalesforceId::new("001000000000001AAA").must();
let original = CreateResponse::success(id);
let json = serde_json::to_string(&original).must();
let deserialized: CreateResponse = serde_json::from_str(&json).must();
assert_eq!(original, deserialized);
}
#[test]
fn test_empty_errors_serialization() {
let response = UpdateResponse::success();
let json = serde_json::to_string(&response).must();
let parsed: serde_json::Value = serde_json::from_str(&json).must();
assert!(parsed.get("errors").is_some());
}
}