oas3 0.2.1

Structures and tools to parse, navigate and validate OpenAPI v3 specifications.
Documentation
use std::fmt;

use derive_more::Display;
use log::debug;
use http::{Method, StatusCode};

use crate::{spec::Operation, validation::Error as ValidationError, Spec};

#[derive(Debug, Clone, Display)]
pub enum OperationSpec {
    #[display(fmt = "{} {}", method, path)]
    Parts { method: Method, path: String },

    #[display(fmt = "OpID: {}", _0)]
    OperationId(String),
}

impl OperationSpec {
    pub fn new<P: Into<String>>(method: Method, path: P) -> Self {
        Self::Parts {
            method,
            path: path.into(),
        }
    }

    pub fn get<P: Into<String>>(path: P) -> Self {
        Self::new(Method::GET, path)
    }
    pub fn post<P: Into<String>>(path: P) -> Self {
        Self::new(Method::POST, path)
    }
    pub fn patch<P: Into<String>>(path: P) -> Self {
        Self::new(Method::PATCH, path)
    }
    pub fn put<P: Into<String>>(path: P) -> Self {
        Self::new(Method::PUT, path)
    }
    pub fn delete<P: Into<String>>(path: P) -> Self {
        Self::new(Method::DELETE, path)
    }

    pub fn operation_id<P: Into<String>>(op_id: P) -> Self {
        Self::OperationId(op_id.into())
    }
}

#[derive(Debug, Clone)]
pub struct TestOperation {
    pub method: Method,
    pub path: String,
}

impl TestOperation {
    pub fn new<P: Into<String>>(method: Method, path: P) -> Self {
        Self {
            method,
            path: path.into(),
        }
    }

    pub fn resolve_operation<'a>(&self, spec: &'a Spec) -> Result<&'a Operation, ValidationError> {
        debug!("resolving op {:?}", &self);
        
        spec.operation(&self.method, &self.path).ok_or_else(|| {
            ValidationError::OperationNotFound(self.method.clone(), self.path.clone())
        })
    }
}