schemadoc_diff/
schema_diff_utils.rs

1use crate::core::{DiffResult, PathResolver, VecDiffTransformer};
2use regex::Regex;
3use std::collections::HashMap;
4
5/// Moves `null` in `schema.type` to the end of array
6#[derive(Debug, Default, Clone)]
7pub struct TypeVecDiffSorter;
8
9impl VecDiffTransformer<Vec<DiffResult<String>>> for TypeVecDiffSorter {
10    fn transform(
11        mut vector: Vec<DiffResult<String>>,
12    ) -> Vec<DiffResult<String>> {
13        let index = vector.iter().position(|v| match v.get() {
14            Some(value) => value == "null",
15            None => false,
16        });
17
18        if let Some(index) = index {
19            let value = vector.remove(index);
20            vector.push(value)
21        }
22
23        vector
24    }
25}
26
27/// Tries to find paths from `.paths` with same endpoints and different path's parameter names
28/// Example:
29///     `v1/datasets/{name}/tags` considers the same endpoint as `v1/datasets/{uuid}/tags`
30/// Right now we do not care about parameter type when merging
31#[derive(Debug, Clone)]
32pub struct PathsMapPathResolver(
33    HashMap<String, String>,
34    HashMap<String, String>,
35);
36
37fn get_key(key: &str) -> String {
38    let re = Regex::new(r"\{.+?}").unwrap();
39    re.replace_all(key, "$").to_string()
40}
41
42impl PathResolver for PathsMapPathResolver {
43    fn new<'a, T>(k1: T, k2: T) -> Self
44    where
45        T: Iterator<Item = &'a String>,
46    {
47        let keys1: HashMap<_, _> =
48            k1.map(|key| (get_key(key), key.clone())).collect();
49
50        let keys2: HashMap<_, _> =
51            k2.map(|key| (get_key(key), key.clone())).collect();
52
53        Self(keys1, keys2)
54    }
55
56    fn k1tok2(&self, k1: &String) -> String {
57        let key = get_key(k1);
58        self.1.get(&key).unwrap_or(k1).to_owned()
59    }
60
61    fn k2tok1(&self, k2: &String) -> String {
62        let key = get_key(k2);
63        self.0.get(&key).unwrap_or(k2).to_owned()
64    }
65}