Skip to content

do not clone Schema, clone only when the inner struct is Bool #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 34 additions & 52 deletions src/diff_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ impl<F: FnMut(Change)> DiffWalker<F> {
if let (Some(lhs_any_of), Some(rhs_any_of)) =
(&mut lhs.subschemas().any_of, &mut rhs.subschemas().any_of)
{
match (lhs_any_of.len(), rhs_any_of.len()) {
(l, r) if l <= r => {
lhs_any_of.append(&mut vec![Schema::Bool(false); r - l]);
}
(l, r) => {
rhs_any_of.append(&mut vec![Schema::Bool(false); l - r]);
}
}
let max_len = lhs_any_of.len().max(rhs_any_of.len());
lhs_any_of.resize(max_len, Schema::Bool(false));
rhs_any_of.resize(max_len, Schema::Bool(false));
Expand All @@ -57,11 +49,7 @@ impl<F: FnMut(Change)> DiffWalker<F> {
self.lhs_root.clone(),
self.rhs_root.clone(),
)
.diff(
"",
&mut l.clone().into_object(),
&mut r.clone().into_object(),
)?;
.diff("", l, r)?;
mat[(i, j)] = count;
}
}
Expand Down Expand Up @@ -178,15 +166,11 @@ impl<F: FnMut(Change)> DiffWalker<F> {
}

for common in rhs_props.intersection(&lhs_props) {
let lhs_child = lhs.object().properties.get(common.as_str()).unwrap();
let rhs_child = rhs.object().properties.get(common.as_str()).unwrap();
let lhs_child = lhs.object().properties.get_mut(common.as_str()).unwrap();
let rhs_child = rhs.object().properties.get_mut(common.as_str()).unwrap();

let new_path = format!("{json_path}.{common}");
self.diff(
&new_path,
&mut lhs_child.clone().into_object(),
&mut rhs_child.clone().into_object(),
)?;
self.diff(&new_path, lhs_child, rhs_child)?;
}

Ok(())
Expand All @@ -198,17 +182,17 @@ impl<F: FnMut(Change)> DiffWalker<F> {
lhs: &mut SchemaObject,
rhs: &mut SchemaObject,
) -> Result<(), Error> {
if let (Some(ref lhs_additional_properties), Some(ref rhs_additional_properties)) = (
&lhs.object().additional_properties,
&rhs.object().additional_properties,
if let (Some(lhs_additional_properties), Some(rhs_additional_properties)) = (
&mut lhs.object().additional_properties,
&mut rhs.object().additional_properties,
) {
if rhs_additional_properties != lhs_additional_properties {
let new_path = format!("{json_path}.<additionalProperties>");

self.diff(
&new_path,
&mut lhs_additional_properties.clone().into_object(),
&mut rhs_additional_properties.clone().into_object(),
lhs_additional_properties,
rhs_additional_properties,
)?;
}
}
Expand Down Expand Up @@ -270,7 +254,7 @@ impl<F: FnMut(Change)> DiffWalker<F> {
lhs: &mut SchemaObject,
rhs: &mut SchemaObject,
) -> Result<(), Error> {
match (&lhs.array().items, &rhs.array().items) {
match (&mut lhs.array().items, &mut rhs.array().items) {
(Some(SingleOrVec::Vec(lhs_items)), Some(SingleOrVec::Vec(rhs_items))) => {
if lhs_items.len() != rhs_items.len() {
(self.cb)(Change {
Expand All @@ -282,23 +266,15 @@ impl<F: FnMut(Change)> DiffWalker<F> {
}

for (i, (lhs_inner, rhs_inner)) in
lhs_items.iter().zip(rhs_items.iter()).enumerate()
lhs_items.iter_mut().zip(rhs_items.iter_mut()).enumerate()
{
let new_path = format!("{json_path}.{i}");
self.diff(
&new_path,
&mut lhs_inner.clone().into_object(),
&mut rhs_inner.clone().into_object(),
)?;
self.diff(&new_path, lhs_inner, rhs_inner)?;
}
}
(Some(SingleOrVec::Single(lhs_inner)), Some(SingleOrVec::Single(rhs_inner))) => {
let new_path = format!("{json_path}.?");
self.diff(
&new_path,
&mut lhs_inner.clone().into_object(),
&mut rhs_inner.clone().into_object(),
)?;
self.diff(&new_path, lhs_inner, rhs_inner)?;
}
(Some(SingleOrVec::Single(lhs_inner)), Some(SingleOrVec::Vec(rhs_items))) => {
(self.cb)(Change {
Expand All @@ -308,13 +284,9 @@ impl<F: FnMut(Change)> DiffWalker<F> {
},
});

for (i, rhs_inner) in rhs_items.iter().enumerate() {
for (i, rhs_inner) in rhs_items.iter_mut().enumerate() {
let new_path = format!("{json_path}.{i}");
self.diff(
&new_path,
&mut lhs_inner.clone().into_object(),
&mut rhs_inner.clone().into_object(),
)?;
self.diff(&new_path, lhs_inner, rhs_inner)?;
}
}
(Some(SingleOrVec::Vec(lhs_items)), Some(SingleOrVec::Single(rhs_inner))) => {
Expand All @@ -325,13 +297,9 @@ impl<F: FnMut(Change)> DiffWalker<F> {
},
});

for (i, lhs_inner) in lhs_items.iter().enumerate() {
for (i, lhs_inner) in lhs_items.iter_mut().enumerate() {
let new_path = format!("{json_path}.{i}");
self.diff(
&new_path,
&mut lhs_inner.clone().into_object(),
&mut rhs_inner.clone().into_object(),
)?;
self.diff(&new_path, lhs_inner, rhs_inner)?;
}
}
(None, None) => (),
Expand Down Expand Up @@ -507,10 +475,24 @@ impl<F: FnMut(Change)> DiffWalker<F> {
pub fn diff(
&mut self,
json_path: &str,
lhs: &mut SchemaObject,
rhs: &mut SchemaObject,
lhs: &mut Schema,
rhs: &mut Schema,
) -> Result<(), Error> {
self.do_diff(json_path, false, lhs, rhs)
match (lhs, rhs) {
(Schema::Object(lhs), Schema::Object(rhs)) => self.do_diff(json_path, false, lhs, rhs),
(bool_lhs, Schema::Object(rhs)) => {
self.do_diff(json_path, false, &mut bool_lhs.clone().into_object(), rhs)
}
(Schema::Object(lhs), bool_rhs) => {
self.do_diff(json_path, false, lhs, &mut bool_rhs.clone().into_object())
}
(bool_lhs, bool_rhs) => self.do_diff(
json_path,
false,
&mut bool_lhs.clone().into_object(),
&mut bool_rhs.clone().into_object(),
),
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

use schemars::schema::RootSchema;
use schemars::schema::{RootSchema, Schema};
use serde_json::Value;
use thiserror::Error;

Expand All @@ -27,8 +27,8 @@ pub fn diff(lhs: Value, rhs: Value) -> Result<Vec<Change>, Error> {
);
walker.diff(
"",
&mut walker.lhs_root.schema.clone(),
&mut walker.rhs_root.schema.clone(),
&mut Schema::Object(walker.lhs_root.schema.clone()),
&mut Schema::Object(walker.rhs_root.schema.clone()),
)?;
Ok(changes)
}