schemadoc_diff/
lib.rs

1pub mod checker;
2pub mod context;
3pub mod core;
4pub mod diff_own_changes;
5pub mod diff_result_type;
6pub mod error;
7pub mod exporters;
8pub mod path_pointer;
9pub mod schema;
10pub mod schema_diff;
11pub mod schema_diff_utils;
12pub mod schemas;
13pub mod visitor;
14pub mod visitors;
15
16use crate::context::HttpSchemaDiffContext;
17use crate::core::{Diff, DiffResult};
18use once_cell::sync::Lazy;
19use std::rc::Rc;
20use tracing::info;
21
22use crate::error::Error;
23use crate::schema::HttpSchema;
24use crate::schema_diff::HttpSchemaDiff;
25use crate::schemas::openapi303::schema::OpenApi303;
26use crate::schemas::openapi310::schema::OpenApi310;
27use crate::schemas::swagger2::schema::SwaggerV2;
28
29use crate::schemas::openapi303::converter::VERSION as OPENAPI303_CONVERTER_VERSION;
30use crate::schemas::openapi310::converter::VERSION as OPENAPI310_CONVERTER_VERSION;
31use crate::schemas::swagger2::converter::VERSION as SWAGGERV2_CONVERTER_VERSION;
32
33pub static VERSIONS: Lazy<Vec<String>> = Lazy::new(|| {
34    let schema_version = schema::HttpSchema::schema_version();
35    vec![
36        format!(
37            "{}-{}-{}",
38            schema_version,
39            SwaggerV2::id(),
40            SWAGGERV2_CONVERTER_VERSION
41        ),
42        format!(
43            "{}-{}-{}",
44            schema_version,
45            OpenApi303::id(),
46            OPENAPI303_CONVERTER_VERSION
47        ),
48        format!(
49            "{}-{}-{}",
50            schema_version,
51            OpenApi310::id(),
52            OPENAPI310_CONVERTER_VERSION
53        ),
54    ]
55});
56
57pub fn is_current_diff_version(diff_version: &str) -> bool {
58    VERSIONS.iter().any(|x| x == diff_version)
59}
60
61#[tracing::instrument(skip_all, fields(src.schema.decoder, src.schema.version, tgt.schema.decoder, tgt.schema.version))]
62pub fn try_deserialize_schema(
63    src_content: &str,
64    tgt_content: &str,
65) -> Result<(schema::HttpSchema, schema::HttpSchema), Error> {
66    let source: schema::HttpSchema = if let Ok(schema) =
67        serde_json::from_str::<OpenApi310>(src_content)
68    {
69        Ok(schema.into())
70    } else if let Ok(schema) = serde_json::from_str::<OpenApi303>(src_content)
71    {
72        Ok(schema.into())
73    } else if let Ok(schema) = serde_json::from_str::<SwaggerV2>(src_content) {
74        Ok(schema.into())
75    } else {
76        Err(Error::InvalidSourceSchema)
77    }?;
78
79    info!(
80        src.schema.version = &source.version,
81        src.schema.decoder = &source.schema_source
82    );
83
84    let target: schema::HttpSchema = if let Ok(schema) =
85        serde_json::from_str::<OpenApi310>(tgt_content)
86    {
87        Ok(schema.into())
88    } else if let Ok(schema) = serde_json::from_str::<OpenApi303>(tgt_content)
89    {
90        Ok(schema.into())
91    } else if let Ok(schema) = serde_json::from_str::<SwaggerV2>(tgt_content) {
92        Ok(schema.into())
93    } else {
94        Err(Error::InvalidTargetSchema)
95    }?;
96
97    info!(
98        tgt.schema.version = &target.version,
99        tgt.schema.decoder = &target.schema_source
100    );
101
102    Ok((source, target))
103}
104
105pub fn get_schema_diff(
106    src_schema: HttpSchema,
107    tgt_schema: HttpSchema,
108) -> DiffResult<HttpSchemaDiff> {
109    let src = Rc::new(src_schema);
110    let tgt = Rc::new(tgt_schema);
111
112    let context = HttpSchemaDiffContext::new(Rc::clone(&src), Rc::clone(&tgt));
113    src.diff(Some(&*tgt), &context)
114}