mockforge_core/openapi/
schema.rs

1//! OpenAPI schema validation and handling
2//!
3//! This module provides functionality for working with OpenAPI schemas,
4//! including validation, type checking, and schema manipulation.
5
6use crate::{Error, Result};
7use jsonschema::{self, Draft};
8use openapiv3::Schema;
9use serde_json::Value;
10
11/// OpenAPI schema wrapper with additional functionality
12#[derive(Debug, Clone)]
13pub struct OpenApiSchema {
14    /// The underlying OpenAPI schema
15    pub schema: Schema,
16}
17
18impl OpenApiSchema {
19    /// Create a new OpenApiSchema from an OpenAPI Schema
20    pub fn new(schema: Schema) -> Self {
21        Self { schema }
22    }
23
24    /// Validate a value against this schema
25    pub fn validate(&self, value: &Value) -> Result<()> {
26        // Convert OpenAPI schema to JSON Schema for validation
27        match serde_json::to_value(&self.schema) {
28            Ok(schema_json) => {
29                // Create JSON Schema validator
30                match jsonschema::options().with_draft(Draft::Draft7).build(&schema_json) {
31                    Ok(validator) => {
32                        // Validate the value against the schema
33                        let errors: Vec<String> =
34                            validator.iter_errors(value).map(|error| error.to_string()).collect();
35                        if errors.is_empty() {
36                            Ok(())
37                        } else {
38                            Err(Error::validation(errors.join("; ")))
39                        }
40                    }
41                    Err(e) => {
42                        Err(Error::validation(format!("Failed to create schema validator: {}", e)))
43                    }
44                }
45            }
46            Err(e) => {
47                Err(Error::validation(format!("Failed to convert OpenAPI schema to JSON: {}", e)))
48            }
49        }
50    }
51}
52
53/// Schema validation result
54#[derive(Debug, Clone)]
55pub struct ValidationResult {
56    /// Whether validation passed
57    pub valid: bool,
58    /// Validation errors if any
59    pub errors: Vec<String>,
60}
61
62impl ValidationResult {
63    /// Create a successful validation result
64    pub fn valid() -> Self {
65        Self {
66            valid: true,
67            errors: Vec::new(),
68        }
69    }
70
71    /// Create a failed validation result with errors
72    pub fn invalid(errors: Vec<String>) -> Self {
73        Self {
74            valid: false,
75            errors,
76        }
77    }
78}