1use crate::value::Value;
8use std::cmp::Ordering;
9
10#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
19#[error("map value error")]
20pub enum MapValueError {
21 EmptyKey {
22 index: usize,
23 },
24 NonScalarKey {
25 index: usize,
26 key: Value,
27 },
28 NonScalarValue {
29 index: usize,
30 value: Value,
31 },
32 DuplicateKey {
33 left_index: usize,
34 right_index: usize,
35 },
36}
37
38#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
47#[error("schema invariant error")]
48pub enum SchemaInvariantError {
49 InvalidMapValue(MapValueError),
50}
51
52impl From<MapValueError> for SchemaInvariantError {
53 fn from(value: MapValueError) -> Self {
54 Self::InvalidMapValue(value)
55 }
56}
57
58fn validate_map_entries(entries: &[(Value, Value)]) -> Result<(), MapValueError> {
60 for (index, (key, _value)) in entries.iter().enumerate() {
61 if matches!(key, Value::Null) {
62 return Err(MapValueError::EmptyKey { index });
63 }
64 if !key.is_scalar() {
65 return Err(MapValueError::NonScalarKey {
66 index,
67 key: key.clone(),
68 });
69 }
70 }
71
72 Ok(())
73}
74
75fn compare_map_entry_keys(left: &(Value, Value), right: &(Value, Value)) -> Ordering {
77 Value::canonical_cmp_key(&left.0, &right.0)
78}
79
80fn sort_map_entries_in_place(entries: &mut [(Value, Value)]) {
82 entries.sort_unstable_by(compare_map_entry_keys);
83}
84
85fn validate_unique_map_keys<'a>(
88 keys: impl Iterator<Item = &'a Value>,
89) -> Result<(), MapValueError> {
90 let mut previous = None;
91 for (index, key) in keys.enumerate() {
92 if let Some(previous) = previous
93 && Value::canonical_cmp_key(previous, key) == Ordering::Equal
94 {
95 return Err(MapValueError::DuplicateKey {
96 left_index: index - 1,
97 right_index: index,
98 });
99 }
100 previous = Some(key);
101 }
102 Ok(())
103}
104
105pub(super) fn normalize_map_entries(
107 mut entries: Vec<(Value, Value)>,
108) -> Result<Vec<(Value, Value)>, MapValueError> {
109 validate_map_entries(&entries)?;
110 sort_map_entries_in_place(entries.as_mut_slice());
111
112 validate_unique_map_keys(entries.iter().map(|(key, _)| key))?;
113
114 Ok(entries)
115}
116
117impl Value {
118 pub(crate) fn validate_canonical_map_entries(
121 entries: &[(Self, Self)],
122 ) -> Result<(), MapValueError> {
123 validate_map_entries(entries)?;
124 validate_unique_map_keys(Self::ordered_map_entries(entries).map(|(key, _)| key))
125 }
126
127 pub fn validate_map_entries(entries: &[(Self, Self)]) -> Result<(), MapValueError> {
129 validate_map_entries(entries)
130 }
131
132 pub fn normalize_map_entries(
134 entries: Vec<(Self, Self)>,
135 ) -> Result<Vec<(Self, Self)>, MapValueError> {
136 normalize_map_entries(entries)
137 }
138}