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