1use crate::errors::consensus::ConsensusError;
2use crate::version::PlatformVersion;
3use crate::ProtocolError;
4use std::fmt::Debug;
5
6mod flatten;
7mod merge_many;
8
9#[macro_export]
10macro_rules! check_validation_result_with_data {
11 ($result:expr) => {
12 match $result {
13 Ok(result) => result,
14 Err(e) => return Ok(ValidationResult::new_with_errors(vec![e.into()])),
15 }
16 };
17}
18
19pub type SimpleValidationResult<E> = ValidationResult<(), E>;
20
21pub type ConsensusValidationResult<TData> = ValidationResult<TData, ConsensusError>;
22
23pub type SimpleConsensusValidationResult = ConsensusValidationResult<()>;
24
25#[derive(Debug, Clone)]
26pub struct ValidationResult<TData: Clone, E: Debug> {
27 pub errors: Vec<E>,
28 pub data: Option<TData>,
29}
30
31impl<T: Clone, E: Debug> Default for ValidationResult<T, E> {
32 fn default() -> Self {
33 ValidationResult {
34 errors: Vec::new(),
35 data: None,
36 }
37 }
38}
39
40impl<TData: Clone, E: Debug> ValidationResult<Vec<TData>, E> {
41 pub fn flatten<I: IntoIterator<Item = ValidationResult<Vec<TData>, E>>>(
66 items: I,
67 platform_version: &PlatformVersion,
68 ) -> Result<ValidationResult<Vec<TData>, E>, ProtocolError> {
69 match platform_version.dpp.validation.validation_result.flatten {
70 0 => Ok(flatten::v0::flatten_v0(items)),
71 1 => Ok(flatten::v1::flatten_v1(items)),
72 version => Err(ProtocolError::UnknownVersionMismatch {
73 method: "ValidationResult::flatten".to_string(),
74 known_versions: vec![0, 1],
75 received: version,
76 }),
77 }
78 }
79}
80
81impl<TData: Clone, E: Debug> ValidationResult<TData, E> {
82 pub fn merge_many<I: IntoIterator<Item = ValidationResult<TData, E>>>(
102 items: I,
103 platform_version: &PlatformVersion,
104 ) -> Result<ValidationResult<Vec<TData>, E>, ProtocolError> {
105 match platform_version.dpp.validation.validation_result.merge_many {
106 0 => Ok(merge_many::v0::merge_many_v0(items)),
107 1 => Ok(merge_many::v1::merge_many_v1(items)),
108 version => Err(ProtocolError::UnknownVersionMismatch {
109 method: "ValidationResult::merge_many".to_string(),
110 known_versions: vec![0, 1],
111 received: version,
112 }),
113 }
114 }
115}
116
117impl<E: Debug> SimpleValidationResult<E> {
118 pub fn merge_many_errors<I: IntoIterator<Item = SimpleValidationResult<E>>>(
119 items: I,
120 ) -> SimpleValidationResult<E> {
121 let errors = items
122 .into_iter()
123 .flat_map(|single_validation_result| single_validation_result.errors)
124 .collect();
125 SimpleValidationResult::new_with_errors(errors)
126 }
127}
128
129impl<TData: Clone, E: Debug> ValidationResult<TData, E> {
130 pub fn new() -> Self {
131 Self {
132 errors: vec![],
133 data: None::<TData>,
134 }
135 }
136
137 pub fn new_with_data(data: TData) -> Self {
138 Self {
139 errors: vec![],
140 data: Some(data),
141 }
142 }
143
144 pub fn new_with_data_and_errors(data: TData, errors: Vec<E>) -> Self {
145 Self {
146 errors,
147 data: Some(data),
148 }
149 }
150
151 pub fn new_with_error(error: E) -> Self {
152 Self {
153 errors: vec![error],
154 data: None,
155 }
156 }
157
158 pub fn new_with_errors(errors: Vec<E>) -> Self {
159 Self { errors, data: None }
160 }
161
162 pub fn map<F, U: Clone>(self, f: F) -> ValidationResult<U, E>
163 where
164 F: FnOnce(TData) -> U,
165 {
166 ValidationResult {
167 errors: self.errors,
168 data: self.data.map(f),
169 }
170 }
171
172 pub fn map_result<F, U: Clone, G>(self, f: F) -> Result<ValidationResult<U, E>, G>
173 where
174 F: FnOnce(TData) -> Result<U, G>,
175 {
176 Ok(ValidationResult {
177 errors: self.errors,
178 data: self.data.map(f).transpose()?,
179 })
180 }
181
182 pub fn and_then_simple_validation<F>(
183 self,
184 f: F,
185 ) -> Result<ValidationResult<TData, E>, ProtocolError>
186 where
187 F: FnOnce(&TData) -> Result<SimpleValidationResult<E>, ProtocolError>,
188 {
189 let new_errors = self.data.as_ref().map(f).transpose()?;
190 let mut result = ValidationResult {
191 errors: self.errors,
192 data: self.data,
193 };
194 if let Some(new_errors) = new_errors {
195 result.add_errors(new_errors.errors)
196 }
197 Ok(result)
198 }
199
200 pub fn and_then_validation<F, U: Clone, G>(self, f: F) -> Result<ValidationResult<U, E>, G>
201 where
202 F: FnOnce(TData) -> Result<ValidationResult<U, E>, G>,
203 {
204 if let Some(data) = self.data {
205 let mut new_validation_result = f(data)?;
206 new_validation_result.add_errors(self.errors);
207 Ok(new_validation_result)
208 } else {
209 Ok(ValidationResult::<U, E>::new_with_errors(self.errors))
210 }
211 }
212
213 pub fn and_then_borrowed_validation<F, U: Clone, G>(
214 self,
215 f: F,
216 ) -> Result<ValidationResult<U, E>, G>
217 where
218 F: FnOnce(&TData) -> Result<ValidationResult<U, E>, G>,
219 {
220 if let Some(data) = self.data.as_ref() {
221 let mut new_validation_result = f(data)?;
222 new_validation_result.add_errors(self.errors);
223 Ok(new_validation_result)
224 } else {
225 Ok(ValidationResult::<U, E>::new_with_errors(self.errors))
226 }
227 }
228
229 pub fn add_error<T>(&mut self, error: T)
230 where
231 T: Into<E>,
232 {
233 self.errors.push(error.into())
234 }
235
236 pub fn add_errors(&mut self, mut errors: Vec<E>) {
237 self.errors.append(&mut errors)
238 }
239
240 pub fn add_errors_into<EI: Into<E>>(&mut self, errors: Vec<EI>) {
241 errors.into_iter().for_each(|e| self.add_error(e.into()))
242 }
243
244 pub fn merge<TOtherData: Clone>(&mut self, mut other: ValidationResult<TOtherData, E>) {
245 self.errors.append(&mut other.errors);
246 }
247
248 pub fn is_valid(&self) -> bool {
249 self.errors.is_empty()
250 }
251
252 pub fn is_err(&self) -> bool {
253 !self.errors.is_empty()
254 }
255
256 pub fn first_error(&self) -> Option<&E> {
257 self.errors.first()
258 }
259
260 pub fn get_error(&self, pos: usize) -> Option<&E> {
261 self.errors.get(pos)
262 }
263
264 pub fn into_result_without_data(self) -> ValidationResult<(), E> {
265 ValidationResult {
266 errors: self.errors,
267 data: None,
268 }
269 }
270
271 pub fn is_valid_with_data(&self) -> bool {
272 self.is_valid() && self.data.is_some()
273 }
274
275 pub fn has_data(&self) -> bool {
276 self.data.is_some()
277 }
278
279 pub fn set_data(&mut self, data: TData) {
280 self.data = Some(data)
281 }
282
283 pub fn into_data(self) -> Result<TData, ProtocolError> {
284 self.data
285 .ok_or(ProtocolError::CorruptedCodeExecution(format!(
286 "trying to push validation result into data (errors are {:?})",
287 self.errors
288 )))
289 }
290
291 pub fn into_data_with_error(mut self) -> Result<Result<TData, E>, ProtocolError> {
292 if let Some(error) = self.errors.pop() {
293 Ok(Err(error))
294 } else {
295 self.data
296 .map(Ok)
297 .ok_or(ProtocolError::CorruptedCodeExecution(format!(
298 "trying to push validation result into data (errors are {:?})",
299 self.errors
300 )))
301 }
302 }
303
304 pub fn into_data_and_errors(self) -> Result<(TData, Vec<E>), ProtocolError> {
305 Ok((
306 self.data
307 .ok_or(ProtocolError::CorruptedCodeExecution(format!(
308 "trying to push validation result into data (errors are {:?})",
309 self.errors
310 )))?,
311 self.errors,
312 ))
313 }
314
315 pub fn data_as_borrowed(&self) -> Result<&TData, ProtocolError> {
316 self.data
317 .as_ref()
318 .ok_or(ProtocolError::CorruptedCodeExecution(format!(
319 "trying to get validation result as data (errors are {:?})",
320 self.errors
321 )))
322 }
323}
324
325impl<TData: Clone, E: Debug> From<TData> for ValidationResult<TData, E> {
326 fn from(value: TData) -> Self {
327 ValidationResult::new_with_data(value)
328 }
329}
330
331impl<TData: Clone, E: Debug, F: Into<E>> From<Result<TData, F>> for ValidationResult<TData, E> {
332 fn from(value: Result<TData, F>) -> Self {
333 match value {
334 Ok(data) => ValidationResult::new_with_data(data),
335 Err(e) => ValidationResult::new_with_errors(vec![e.into()]),
336 }
337 }
338}
339
340#[cfg(test)]
341mod tests {
342 use super::*;
343
344 #[test]
347 fn test_new_has_no_errors() {
348 let result: ValidationResult<i32, String> = ValidationResult::new();
349 assert!(result.errors.is_empty());
350 }
351
352 #[test]
353 fn test_new_has_no_data() {
354 let result: ValidationResult<i32, String> = ValidationResult::new();
355 assert!(result.data.is_none());
356 }
357
358 #[test]
361 fn test_new_with_data_stores_data() {
362 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(42);
363 assert_eq!(result.data, Some(42));
364 assert!(result.errors.is_empty());
365 }
366
367 #[test]
370 fn test_new_with_error_stores_single_error() {
371 let result: ValidationResult<i32, String> =
372 ValidationResult::new_with_error("bad".to_string());
373 assert_eq!(result.errors.len(), 1);
374 assert_eq!(result.errors[0], "bad");
375 assert!(result.data.is_none());
376 }
377
378 #[test]
381 fn test_new_with_errors_stores_multiple_errors() {
382 let result: ValidationResult<i32, String> =
383 ValidationResult::new_with_errors(vec!["a".to_string(), "b".to_string()]);
384 assert_eq!(result.errors.len(), 2);
385 assert_eq!(result.errors[0], "a");
386 assert_eq!(result.errors[1], "b");
387 assert!(result.data.is_none());
388 }
389
390 #[test]
391 fn test_new_with_errors_empty_vec() {
392 let result: ValidationResult<i32, String> = ValidationResult::new_with_errors(vec![]);
393 assert!(result.errors.is_empty());
394 assert!(result.data.is_none());
395 }
396
397 #[test]
400 fn test_map_transforms_data() {
401 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(10);
402 let mapped = result.map(|x| x * 2);
403 assert_eq!(mapped.data, Some(20));
404 assert!(mapped.errors.is_empty());
405 }
406
407 #[test]
408 fn test_map_preserves_errors() {
409 let result: ValidationResult<i32, String> =
410 ValidationResult::new_with_data_and_errors(5, vec!["err".to_string()]);
411 let mapped = result.map(|x| x + 1);
412 assert_eq!(mapped.data, Some(6));
413 assert_eq!(mapped.errors, vec!["err".to_string()]);
414 }
415
416 #[test]
417 fn test_map_with_no_data() {
418 let result: ValidationResult<i32, String> =
419 ValidationResult::new_with_error("err".to_string());
420 let mapped = result.map(|x| x + 1);
421 assert!(mapped.data.is_none());
422 assert_eq!(mapped.errors.len(), 1);
423 }
424
425 #[test]
428 fn test_map_result_with_ok_closure() {
429 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(10);
430 let mapped: Result<ValidationResult<String, String>, String> =
431 result.map_result(|x| Ok(format!("val={}", x)));
432 let mapped = mapped.unwrap();
433 assert_eq!(mapped.data, Some("val=10".to_string()));
434 }
435
436 #[test]
437 fn test_map_result_with_err_closure() {
438 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(10);
439 let mapped: Result<ValidationResult<i32, String>, String> =
440 result.map_result(|_| Err("fail".to_string()));
441 assert!(mapped.is_err());
442 assert_eq!(mapped.unwrap_err(), "fail");
443 }
444
445 #[test]
446 fn test_map_result_with_no_data() {
447 let result: ValidationResult<i32, String> =
448 ValidationResult::new_with_error("err".to_string());
449 let mapped: Result<ValidationResult<i32, String>, String> =
450 result.map_result(|x| Ok(x + 1));
451 let mapped = mapped.unwrap();
452 assert!(mapped.data.is_none());
453 assert_eq!(mapped.errors, vec!["err".to_string()]);
454 }
455
456 #[test]
459 fn test_is_valid_true_when_no_errors() {
460 let result: ValidationResult<i32, String> = ValidationResult::new();
461 assert!(result.is_valid());
462 assert!(!result.is_err());
463 }
464
465 #[test]
466 fn test_is_valid_false_when_errors_present() {
467 let result: ValidationResult<i32, String> =
468 ValidationResult::new_with_error("e".to_string());
469 assert!(!result.is_valid());
470 assert!(result.is_err());
471 }
472
473 #[test]
474 fn test_is_valid_with_data_and_no_errors() {
475 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(1);
476 assert!(result.is_valid());
477 }
478
479 #[test]
480 fn test_is_err_with_data_and_errors() {
481 let result: ValidationResult<i32, String> =
482 ValidationResult::new_with_data_and_errors(1, vec!["e".to_string()]);
483 assert!(result.is_err());
484 }
485
486 #[test]
489 fn test_first_error_returns_first() {
490 let result: ValidationResult<i32, String> =
491 ValidationResult::new_with_errors(vec!["first".to_string(), "second".to_string()]);
492 assert_eq!(result.first_error(), Some(&"first".to_string()));
493 }
494
495 #[test]
496 fn test_first_error_returns_none_when_no_errors() {
497 let result: ValidationResult<i32, String> = ValidationResult::new();
498 assert_eq!(result.first_error(), None);
499 }
500
501 #[test]
504 fn test_into_data_returns_data_when_present() {
505 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(42);
506 assert_eq!(result.into_data().unwrap(), 42);
507 }
508
509 #[test]
510 fn test_into_data_returns_error_when_no_data() {
511 let result: ValidationResult<i32, String> = ValidationResult::new();
512 assert!(result.into_data().is_err());
513 }
514
515 #[test]
518 fn test_into_data_with_error_returns_data_when_valid() {
519 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(42);
520 let inner = result.into_data_with_error().unwrap();
521 assert_eq!(inner.unwrap(), 42);
522 }
523
524 #[test]
525 fn test_into_data_with_error_returns_last_error_when_errors_present() {
526 let result: ValidationResult<i32, String> =
527 ValidationResult::new_with_errors(vec!["first".to_string(), "last".to_string()]);
528 let inner = result.into_data_with_error().unwrap();
529 assert_eq!(inner.unwrap_err(), "last");
530 }
531
532 #[test]
533 fn test_into_data_with_error_returns_protocol_error_when_no_data_and_no_errors() {
534 let result: ValidationResult<i32, String> = ValidationResult::new();
535 assert!(result.into_data_with_error().is_err());
536 }
537
538 #[test]
541 fn test_into_data_and_errors_returns_both() {
542 let result: ValidationResult<i32, String> =
543 ValidationResult::new_with_data_and_errors(10, vec!["e".to_string()]);
544 let (data, errors) = result.into_data_and_errors().unwrap();
545 assert_eq!(data, 10);
546 assert_eq!(errors, vec!["e".to_string()]);
547 }
548
549 #[test]
550 fn test_into_data_and_errors_returns_empty_errors_when_valid() {
551 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(10);
552 let (data, errors) = result.into_data_and_errors().unwrap();
553 assert_eq!(data, 10);
554 assert!(errors.is_empty());
555 }
556
557 #[test]
558 fn test_into_data_and_errors_fails_without_data() {
559 let result: ValidationResult<i32, String> =
560 ValidationResult::new_with_error("e".to_string());
561 assert!(result.into_data_and_errors().is_err());
562 }
563
564 #[test]
567 fn test_from_data_creates_valid_result() {
568 let result: ValidationResult<i32, String> = 42.into();
569 assert_eq!(result.data, Some(42));
570 assert!(result.errors.is_empty());
571 }
572
573 #[test]
574 fn test_from_ok_result_creates_valid_result() {
575 let ok_result: Result<i32, String> = Ok(42);
576 let result: ValidationResult<i32, String> = ok_result.into();
577 assert_eq!(result.data, Some(42));
578 assert!(result.errors.is_empty());
579 }
580
581 #[test]
582 fn test_from_err_result_creates_error_result() {
583 let err_result: Result<i32, String> = Err("bad".to_string());
584 let result: ValidationResult<i32, String> = err_result.into();
585 assert!(result.data.is_none());
586 assert_eq!(result.errors, vec!["bad".to_string()]);
587 }
588
589 #[test]
596 fn test_facade_flatten_v0_returns_some_empty_on_no_data() {
597 let pv = PlatformVersion::get(11).expect("v11 exists");
599 let r1: ValidationResult<Vec<i32>, ConsensusError> =
600 ValidationResult::new_with_errors(vec![]);
601 let flat = ValidationResult::flatten(vec![r1], pv).expect("dispatch ok");
602 assert_eq!(flat.data, Some(vec![]));
603 }
604
605 #[test]
606 fn test_facade_flatten_v1_returns_none_on_no_data() {
607 let pv = PlatformVersion::get(12).expect("v12 exists");
609 let r1: ValidationResult<Vec<i32>, ConsensusError> =
610 ValidationResult::new_with_errors(vec![]);
611 let flat = ValidationResult::flatten(vec![r1], pv).expect("dispatch ok");
612 assert!(flat.data.is_none());
613 }
614
615 #[test]
616 fn test_facade_merge_many_v0_returns_some_empty_on_no_data() {
617 let pv = PlatformVersion::get(11).expect("v11 exists");
618 let r1: ValidationResult<i32, ConsensusError> = ValidationResult::new_with_errors(vec![]);
619 let merged = ValidationResult::merge_many(vec![r1], pv).expect("dispatch ok");
620 assert_eq!(merged.data, Some(vec![]));
621 }
622
623 #[test]
624 fn test_facade_merge_many_v1_returns_none_on_no_data() {
625 let pv = PlatformVersion::get(12).expect("v12 exists");
626 let r1: ValidationResult<i32, ConsensusError> = ValidationResult::new_with_errors(vec![]);
627 let merged = ValidationResult::merge_many(vec![r1], pv).expect("dispatch ok");
628 assert!(merged.data.is_none());
629 }
630
631 #[test]
634 fn test_merge_many_errors_collects_all_errors() {
635 let r1: SimpleValidationResult<String> =
636 SimpleValidationResult::new_with_errors(vec!["a".to_string()]);
637 let r2: SimpleValidationResult<String> =
638 SimpleValidationResult::new_with_errors(vec!["b".to_string(), "c".to_string()]);
639 let r3: SimpleValidationResult<String> = SimpleValidationResult::new();
640
641 let merged = SimpleValidationResult::merge_many_errors(vec![r1, r2, r3]);
642 assert_eq!(
643 merged.errors,
644 vec!["a".to_string(), "b".to_string(), "c".to_string()]
645 );
646 }
647
648 #[test]
649 fn test_merge_many_errors_empty_input() {
650 let merged: SimpleValidationResult<String> =
651 SimpleValidationResult::merge_many_errors(std::iter::empty());
652 assert!(merged.errors.is_empty());
653 }
654
655 #[test]
658 fn test_default_is_empty() {
659 let result: ValidationResult<i32, String> = ValidationResult::default();
660 assert!(result.errors.is_empty());
661 assert!(result.data.is_none());
662 }
663
664 #[test]
667 fn test_add_error() {
668 let mut result: ValidationResult<i32, String> = ValidationResult::new();
669 result.add_error("e1".to_string());
670 result.add_error("e2".to_string());
671 assert_eq!(result.errors, vec!["e1".to_string(), "e2".to_string()]);
672 }
673
674 #[test]
675 fn test_add_errors() {
676 let mut result: ValidationResult<i32, String> =
677 ValidationResult::new_with_error("e1".to_string());
678 result.add_errors(vec!["e2".to_string(), "e3".to_string()]);
679 assert_eq!(result.errors.len(), 3);
680 }
681
682 #[test]
683 fn test_merge_appends_errors_from_other() {
684 let mut r1: ValidationResult<i32, String> =
685 ValidationResult::new_with_error("a".to_string());
686 let r2: ValidationResult<String, String> =
687 ValidationResult::new_with_error("b".to_string());
688 r1.merge(r2);
689 assert_eq!(r1.errors, vec!["a".to_string(), "b".to_string()]);
690 }
691
692 #[test]
695 fn test_get_error() {
696 let result: ValidationResult<i32, String> =
697 ValidationResult::new_with_errors(vec!["a".to_string(), "b".to_string()]);
698 assert_eq!(result.get_error(0), Some(&"a".to_string()));
699 assert_eq!(result.get_error(1), Some(&"b".to_string()));
700 assert_eq!(result.get_error(2), None);
701 }
702
703 #[test]
704 fn test_has_data() {
705 let with: ValidationResult<i32, String> = ValidationResult::new_with_data(1);
706 let without: ValidationResult<i32, String> = ValidationResult::new();
707 assert!(with.has_data());
708 assert!(!without.has_data());
709 }
710
711 #[test]
712 fn test_is_valid_with_data() {
713 let valid_with_data: ValidationResult<i32, String> = ValidationResult::new_with_data(1);
714 let valid_no_data: ValidationResult<i32, String> = ValidationResult::new();
715 let invalid_with_data: ValidationResult<i32, String> =
716 ValidationResult::new_with_data_and_errors(1, vec!["e".to_string()]);
717 assert!(valid_with_data.is_valid_with_data());
718 assert!(!valid_no_data.is_valid_with_data());
719 assert!(!invalid_with_data.is_valid_with_data());
720 }
721
722 #[test]
723 fn test_set_data() {
724 let mut result: ValidationResult<i32, String> = ValidationResult::new();
725 assert!(result.data.is_none());
726 result.set_data(99);
727 assert_eq!(result.data, Some(99));
728 }
729
730 #[test]
731 fn test_into_result_without_data() {
732 let result: ValidationResult<i32, String> =
733 ValidationResult::new_with_data_and_errors(42, vec!["e".to_string()]);
734 let without_data = result.into_result_without_data();
735 assert!(without_data.data.is_none());
736 assert_eq!(without_data.errors, vec!["e".to_string()]);
737 }
738
739 #[test]
740 fn test_data_as_borrowed() {
741 let result: ValidationResult<i32, String> = ValidationResult::new_with_data(42);
742 assert_eq!(result.data_as_borrowed().unwrap(), &42);
743 }
744
745 #[test]
746 fn test_data_as_borrowed_no_data() {
747 let result: ValidationResult<i32, String> = ValidationResult::new();
748 assert!(result.data_as_borrowed().is_err());
749 }
750}