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}