1
+ use bstr:: ByteSlice ;
1
2
use git_hash:: ObjectId ;
2
3
3
4
use crate :: util:: split_at_pos;
@@ -8,6 +9,65 @@ use crate::{
8
9
9
10
pub const SIGNATURE : Signature = * b"TREE" ;
10
11
12
+ pub mod verify {
13
+ use bstr:: BString ;
14
+ use quick_error:: quick_error;
15
+
16
+ quick_error ! {
17
+ #[ derive( Debug ) ]
18
+ pub enum Error {
19
+ RootWithName { name: BString } {
20
+ display( "The root tree was named '{}', even though it should be empty" , name)
21
+ }
22
+ EntriesCount { actual: u32 , expected: u32 } {
23
+ display( "Expected not more than {} entries to be reachable from the top-level, but actual count was {}" , expected, actual)
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ impl Tree {
30
+ pub fn verify ( & self ) -> Result < ( ) , verify:: Error > {
31
+ fn verify_recursive ( children : & [ Tree ] ) -> Result < Option < u32 > , verify:: Error > {
32
+ if children. is_empty ( ) {
33
+ return Ok ( None ) ;
34
+ }
35
+ let mut entries = 0 ;
36
+ for child in children {
37
+ let actual_num_entries = verify_recursive ( & child. children ) ?;
38
+ if let Some ( actual) = actual_num_entries {
39
+ if actual > child. num_entries {
40
+ return Err ( verify:: Error :: EntriesCount {
41
+ actual,
42
+ expected : child. num_entries ,
43
+ } ) ;
44
+ }
45
+ }
46
+ entries += child. num_entries ;
47
+ }
48
+ Ok ( entries. into ( ) )
49
+ }
50
+
51
+ if !self . name . is_empty ( ) {
52
+ return Err ( verify:: Error :: RootWithName {
53
+ name : self . name . as_bstr ( ) . into ( ) ,
54
+ } ) ;
55
+ }
56
+
57
+ let declared_entries = verify_recursive ( & self . children ) ?;
58
+ if let Some ( actual) = declared_entries {
59
+ if actual > self . num_entries {
60
+ return Err ( verify:: Error :: EntriesCount {
61
+ actual,
62
+ expected : self . num_entries ,
63
+ } ) ;
64
+ }
65
+ }
66
+
67
+ Ok ( ( ) )
68
+ }
69
+ }
70
+
11
71
/// A recursive data structure
12
72
pub fn decode ( data : & [ u8 ] , object_hash : git_hash:: Kind ) -> Option < Tree > {
13
73
let ( tree, data) = one_recursive ( data, object_hash. len_in_bytes ( ) ) ?;
0 commit comments