alphadb/verification/json.rs
1// Copyright (C) 2024 Wibo Kuipers
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16use std::sync::LazyLock;
17
18use serde_json::{Value, Map};
19
20use crate::utils::errors::{Get, ToVerificationIssue};
21use crate::utils::json::{get_json_string as adb_get_json_string, object_iter as adb_object_iter, array_iter as adb_array_iter, exists_in_object as adb_exists_in_object, get_json_object as adb_get_json_object};
22use crate::utils::version_number::parse_version_number as adb_parse_version_number;
23use crate::version_source_verification::VerificationIssue;
24
25/// Verify whether a key exists in serde_json::Value and catch potential errors as Verification issue
26///
27/// # Arguments
28/// * `object` - The JSON value to check
29/// * `key` - The key to check for existence
30/// * `issues` - Vector to store any verification issues
31/// * `version_trace` - Trace of version numbers for error reporting
32///
33/// # Returns
34/// * `bool` - True if key exists, false otherwise
35pub fn exists_in_object(object: &serde_json::Value, key: &str, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> bool {
36 match adb_exists_in_object(object, key) {
37 Ok(v) => v,
38 Err(mut e) => {
39 e.set_version_trace(version_trace);
40 e.to_verification_issue(issues);
41 return false;
42 }
43 }
44}
45
46/// Get JSON object with error handling for verification
47///
48/// # Arguments
49/// * `object` - The JSON value to get object from
50/// * `issues` - Vector to store any verification issues
51/// * `version_trace` - Trace of version numbers for error reporting
52///
53/// # Returns
54/// * `Map<String, Value>` - The JSON object if successful, empty map otherwise
55pub fn get_json_object(object: &serde_json::Value, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> Map<String, Value> {
56 match adb_get_json_object(object) {
57 Ok(v) => v.clone(),
58 Err(mut e) => {
59 e.set_version_trace(version_trace);
60 e.to_verification_issue(issues);
61 return Map::new();
62 }
63 }
64}
65
66/// Get JSON string value with error handling for verification
67///
68/// # Arguments
69/// * `string` - The JSON value to get string from
70/// * `issues` - Vector to store any verification issues
71/// * `version_trace` - Trace of version numbers for error reporting
72///
73/// # Returns
74/// * `&'a str` - The string value if successful, empty string otherwise
75pub fn get_json_string<'a>(string: &'a serde_json::Value, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> &'a str {
76 match adb_get_json_string(string) {
77 Ok(v) => v,
78 Err(mut e) => {
79 e.set_version_trace(version_trace);
80 e.to_verification_issue(issues);
81 return "";
82 }
83 }
84}
85
86/// Check if a JSON object is empty with error handling for verification
87///
88/// # Arguments
89/// * `object` - The JSON value to check
90/// * `issues` - Vector to store any verification issues
91/// * `version_trace` - Trace of version numbers for error reporting
92///
93/// # Returns
94/// * `bool` - True if object is empty, false otherwise
95pub fn object_is_empty(object: &serde_json::Value, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> bool {
96 match adb_get_json_object(object) {
97 Ok(v) => v.is_empty(),
98 Err(mut e) => {
99 e.set_version_trace(version_trace);
100 e.to_verification_issue(issues);
101 return true;
102 }
103 }
104}
105
106/// Get array iterator with error handling for verification
107///
108/// # Arguments
109/// * `array` - The JSON value to get array from
110/// * `issues` - Vector to store any verification issues
111/// * `version_trace` - Trace of version numbers for error reporting
112///
113/// # Returns
114/// * `Vec<serde_json::Value>` - Vector of array values if successful, empty vector otherwise
115pub fn array_iter(array: &serde_json::Value, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> Vec<serde_json::Value> {
116 match adb_array_iter(array) {
117 Ok(v) => v.clone(),
118 Err(mut e) => {
119 e.set_version_trace(version_trace);
120 e.to_verification_issue(issues);
121 return Vec::new();
122 }
123 }
124}
125
126/// Get object iterator with error handling for verification
127///
128/// # Arguments
129/// * `object` - The JSON value to get iterator from
130/// * `issues` - Vector to store any verification issues
131/// * `version_trace` - Trace of version numbers for error reporting
132///
133/// # Returns
134/// * `serde_json::map::Keys<'a>` - Iterator over object keys if successful, empty iterator otherwise
135pub fn object_iter<'a>(object: &'a serde_json::Value, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> serde_json::map::Keys<'a> {
136 static EMPTY_MAP: LazyLock<serde_json::Map<String, serde_json::Value>> = LazyLock::new(|| serde_json::Map::new());
137
138 match adb_object_iter(object) {
139 Ok(v) => v,
140 Err(mut e) => {
141 e.set_version_trace(version_trace);
142 e.to_verification_issue(issues);
143 return EMPTY_MAP.keys();
144 }
145 }
146}
147
148/// Parse version number with error handling for verification
149///
150/// # Arguments
151/// * `version_number` - The version number string to parse
152/// * `issues` - Vector to store any verification issues
153/// * `version_trace` - Trace of version numbers for error reporting
154///
155/// # Returns
156/// * `i32` - Parsed version number if successful, 0 otherwise
157pub fn parse_version_number(version_number: &str, issues: &mut Vec<VerificationIssue>, version_trace: Vec<String>) -> i32 {
158 match adb_parse_version_number(version_number) {
159 Ok(v) => v as i32,
160 Err(mut e) => {
161 e.set_version_trace(version_trace);
162 e.to_verification_issue(issues);
163 return 0;
164 }
165 }
166}