snarkvm_console_program/data/record/
equal.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17
18impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Eq for Record<N, Private> {}
19
20impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> PartialEq for Record<N, Private> {
21    /// Returns `true` if `self` and `other` are equal.
22    fn eq(&self, other: &Self) -> bool {
23        *self.is_equal(other)
24    }
25}
26
27impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Equal<Self> for Record<N, Private> {
28    type Output = Boolean<N>;
29
30    /// Returns `true` if `self` and `other` are equal.
31    fn is_equal(&self, other: &Self) -> Self::Output {
32        // Ensure the `data` lengths are equal.
33        if self.data.len() != other.data.len() {
34            return Boolean::new(false);
35        }
36
37        // Check the `version`.
38        if !(*self.version.is_equal(&other.version)) {
39            return Boolean::new(false);
40        }
41
42        // Check the `owner`, and `nonce`.
43        if !(*self.owner.is_equal(&other.owner) && *self.nonce.is_equal(&other.nonce)) {
44            return Boolean::new(false);
45        }
46
47        // Recursively check each entry for equality.
48        if self
49            .data
50            .iter()
51            .zip_eq(other.data.iter())
52            .all(|((name_a, entry_a), (name_b, entry_b))| *name_a.is_equal(name_b) && *entry_a.is_equal(entry_b))
53        {
54            Boolean::new(true)
55        } else {
56            Boolean::new(false)
57        }
58    }
59
60    /// Returns `true` if `self` and `other` are *not* equal.
61    fn is_not_equal(&self, other: &Self) -> Self::Output {
62        !self.is_equal(other)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use snarkvm_console_network::MainnetV0;
70
71    type CurrentNetwork = MainnetV0;
72
73    fn sample_record() -> Record<CurrentNetwork, Plaintext<CurrentNetwork>> {
74        Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::from_str(
75            r"{
76    owner: aleo14tlamssdmg3d0p5zmljma573jghe2q9n6wz29qf36re2glcedcpqfg4add.private,
77    a: true.private,
78    b: 123456789field.public,
79    c: 0group.private,
80    d: {
81        e: true.private,
82        f: 123456789field.private,
83        g: 0group.private
84    },
85    _nonce: 0group.public,
86    _version: 0u8.public
87}",
88        )
89        .unwrap()
90    }
91
92    fn sample_mismatched_record() -> Record<CurrentNetwork, Plaintext<CurrentNetwork>> {
93        Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::from_str(
94            r"{
95    owner: aleo14tlamssdmg3d0p5zmljma573jghe2q9n6wz29qf36re2glcedcpqfg4add.private,
96    a: true.public,
97    b: 123456789field.public,
98    c: 0group.private,
99    d: {
100        e: true.private,
101        f: 123456789field.private,
102        g: 0group.private
103    },
104    _nonce: 0group.public,
105    _version: 0u8.public
106}",
107        )
108        .unwrap()
109    }
110
111    fn check_is_equal() {
112        // Sample the record.
113        let record = sample_record();
114        let mismatched_record = sample_mismatched_record();
115
116        let candidate = record.is_equal(&record);
117        assert!(*candidate);
118
119        let candidate = record.is_equal(&mismatched_record);
120        assert!(!*candidate);
121    }
122
123    fn check_is_not_equal() {
124        // Sample the record.
125        let record = sample_record();
126        let mismatched_record = sample_mismatched_record();
127
128        let candidate = record.is_not_equal(&mismatched_record);
129        assert!(*candidate);
130
131        let candidate = record.is_not_equal(&record);
132        assert!(!*candidate);
133    }
134
135    #[test]
136    fn test_is_equal() {
137        check_is_equal()
138    }
139
140    #[test]
141    fn test_is_not_equal() {
142        check_is_not_equal()
143    }
144}