1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ use crate :: config:: File ;
5
+ use crate :: config:: Directory ;
6
+ use crate :: file_helper:: get_file;
7
+ use std:: fs;
8
+ use std:: path:: Path ;
9
+ use tracing:: { debug} ;
10
+ use fs_extra:: dir:: get_size;
11
+
12
+ impl Directory {
13
+ /// Create a new `Directory`.
14
+ ///
15
+ /// # Arguments
16
+ ///
17
+ /// * `string` - The string for the Path
18
+ #[ must_use]
19
+ pub fn new ( path : & str ) -> Directory {
20
+ Directory {
21
+ path : path. to_string ( ) ,
22
+ size : None ,
23
+ files : None ,
24
+ recurse : Some ( false ) ,
25
+ exist : None ,
26
+ }
27
+ }
28
+ }
29
+
30
+ pub fn get_dir ( dir : & Directory ) -> Result < Directory , Box < dyn std:: error:: Error > > {
31
+ debug ! ( "In get_dir" ) ;
32
+ match compare_dir_state ( dir) {
33
+ Ok ( d) => {
34
+ Ok ( d)
35
+ } ,
36
+ Err ( e) => {
37
+ Err ( e) ?
38
+ }
39
+ }
40
+ }
41
+
42
+ pub fn set_dir ( dir : & Directory ) -> Result < Directory , Box < dyn std:: error:: Error > > {
43
+ match compare_dir_state ( dir) {
44
+ Ok ( current_dir) => {
45
+ debug ! ( "In set_dir" ) ;
46
+ debug ! ( "dir exist {:?}" , dir. exist) ;
47
+ debug ! ( "expected dir exist {:?}" , dir. exist. unwrap_or( true ) ) ;
48
+
49
+ match ( current_dir. exist . unwrap_or ( true ) , dir. exist . unwrap_or ( true ) ) {
50
+ // if the current dir exists and expected state is exist == true, do nothing
51
+ ( true , true ) | ( false , false ) => {
52
+ return Ok ( current_dir) ;
53
+ }
54
+
55
+ // if the current dir exists and expected state is exist == true, create it
56
+ ( true , false ) => {
57
+ debug ! ( "Deleting directory: {:?}" , dir. path) ;
58
+
59
+ if dir. recurse . unwrap_or ( false ) {
60
+ fs:: remove_dir_all ( dir. path . as_str ( ) ) ?;
61
+ } else {
62
+ fs:: remove_dir ( dir. path . as_str ( ) ) ?;
63
+ }
64
+
65
+ return Ok ( get_dir ( & dir) ?)
66
+ }
67
+
68
+ // if the current dir does not exist and expected state is exist == true, create it
69
+ ( false , true ) => {
70
+ debug ! ( "Creating directory: {:?}" , dir. path) ;
71
+ fs:: create_dir_all ( dir. path . as_str ( ) ) ?;
72
+ return Ok ( get_dir ( & dir) ?)
73
+ }
74
+ }
75
+ } ,
76
+ Err ( e) => {
77
+ Err ( e) ?
78
+ }
79
+ }
80
+ }
81
+
82
+ pub fn export_dir_path ( dir : & Directory ) -> Result < Directory , Box < dyn std:: error:: Error > > {
83
+ // Export the file or directory
84
+ let path = Path :: new ( dir. path . as_str ( ) ) ;
85
+
86
+ match path. exists ( ) {
87
+ false => {
88
+ return Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : None , files : None , recurse : dir. recurse , exist : Some ( false ) } ) ;
89
+ }
90
+ _ => { }
91
+ }
92
+
93
+ match path. is_dir ( ) {
94
+ true => {
95
+ let files: Vec < File > = {
96
+ let dir = fs:: read_dir ( path) ?;
97
+ let mut files = Vec :: new ( ) ;
98
+ for entry in dir {
99
+ let entry = entry?;
100
+ let path = entry. path ( ) ;
101
+ let f = File :: new ( path. to_str ( ) . unwrap ( ) ) ;
102
+ files. push ( get_file ( & f) ?) ;
103
+ }
104
+ files
105
+ } ;
106
+
107
+ let dir_size = get_size ( path) ?;
108
+
109
+ Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : Some ( dir_size) , files : Some ( files) , recurse : dir. recurse , exist : Some ( true ) } )
110
+ }
111
+ false => {
112
+ let path = Path :: new ( path) ;
113
+ let f = File :: new ( path. to_str ( ) . unwrap ( ) ) ;
114
+ let file = get_file ( & f) ?;
115
+ let parent = path. parent ( ) ;
116
+ match parent {
117
+ Some ( parent) => {
118
+ Ok ( Directory { path : parent. to_str ( ) . unwrap ( ) . to_string ( ) , size : file. size , files : vec ! [ file] . into ( ) , recurse : dir. recurse , exist : Some ( true ) } )
119
+ }
120
+ _ => {
121
+ return Err ( "Path is not a file or directory" ) ?;
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ pub fn delete_dir ( dir : & Directory ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
129
+ match compare_dir_state ( dir) {
130
+ Ok ( d) => {
131
+
132
+ if d. exist == Some ( false ) {
133
+ return Ok ( ( ) ) ;
134
+ }
135
+
136
+ if d. recurse == Some ( true ) {
137
+ debug ! ( "Deleting directory: {:?}" , d. path) ;
138
+ fs:: remove_dir_all ( d. path ) ?;
139
+ return Ok ( ( ) ) ;
140
+ }
141
+ else {
142
+ debug ! ( "Deleting directory: {:?}" , d. path) ;
143
+ fs:: remove_dir ( d. path ) ?;
144
+ return Ok ( ( ) ) ;
145
+ }
146
+ } ,
147
+ Err ( e) => {
148
+ Err ( e) ?
149
+ }
150
+ }
151
+ }
152
+
153
+ pub fn compare_dir_state ( dir : & Directory ) -> Result < Directory , Box < dyn std:: error:: Error > > {
154
+ let path = Path :: new ( dir. path . as_str ( ) ) ;
155
+
156
+ match path. exists ( ) {
157
+ false => {
158
+ return Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : None , files : None , recurse : dir. recurse , exist : Some ( false ) } ) ;
159
+ }
160
+ true => {
161
+ match path. is_dir ( ) {
162
+ false => {
163
+ return Err ( "Path is not a directory" ) ?;
164
+ }
165
+ _ => { }
166
+ }
167
+ }
168
+ }
169
+
170
+ let dir_size = get_size ( path) ?;
171
+
172
+ match dir. size {
173
+ Some ( size) => {
174
+ if size != dir_size {
175
+ Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : Some ( dir_size) , files : None , recurse : dir. recurse , exist : Some ( true ) } )
176
+ } else {
177
+ Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : Some ( dir_size) , files : None , recurse : dir. recurse , exist : Some ( true ) } )
178
+ }
179
+ }
180
+ None => {
181
+ Ok ( Directory { path : path. to_str ( ) . unwrap ( ) . to_string ( ) , size : Some ( dir_size) , files : None , recurse : dir. recurse , exist : Some ( true ) } )
182
+ }
183
+ }
184
+ }
0 commit comments