11use anyhow:: { Error , Result } ;
2- use serde:: Deserialize ;
2+ use serde:: { Deserialize , Deserializer } ;
33use std:: fs;
44use std:: net:: IpAddr ;
55use std:: path:: PathBuf ;
6+ use std:: str:: FromStr ;
67
78use super :: cors:: CorsConfigFile ;
89use super :: tls:: TlsConfigFile ;
@@ -12,6 +13,8 @@ pub struct ConfigFile {
1213 pub host : IpAddr ,
1314 pub port : u16 ,
1415 pub verbose : Option < bool > ,
16+ #[ serde( default = "current_working_dir" ) ]
17+ #[ serde( deserialize_with = "canonicalize_some" ) ]
1518 pub root_dir : Option < PathBuf > ,
1619 pub tls : Option < TlsConfigFile > ,
1720 pub cors : Option < CorsConfigFile > ,
@@ -36,6 +39,21 @@ impl ConfigFile {
3639 }
3740}
3841
42+ fn canonicalize_some < ' de , D > ( deserializer : D ) -> Result < Option < PathBuf > , D :: Error >
43+ where
44+ D : Deserializer < ' de > ,
45+ {
46+ let value: & str = Deserialize :: deserialize ( deserializer) ?;
47+ let path = PathBuf :: from_str ( value) . unwrap ( ) ;
48+ let canon = fs:: canonicalize ( path) . unwrap ( ) ;
49+
50+ Ok ( Some ( canon) )
51+ }
52+
53+ fn current_working_dir ( ) -> Option < PathBuf > {
54+ std:: env:: current_dir ( ) . ok ( )
55+ }
56+
3957#[ cfg( test) ]
4058mod tests {
4159 use std:: net:: Ipv4Addr ;
@@ -51,17 +69,19 @@ mod tests {
5169 host = "192.168.0.1"
5270 port = 7878
5371 verbose = true
54- root_dir = "~/Desktop "
72+ root_dir = "./fixtures "
5573 "# ;
5674 let host = IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 0 , 1 ) ) ;
5775 let port = 7878 ;
58- let root_dir = PathBuf :: from_str ( "~/Desktop" ) . unwrap ( ) ;
5976 let config = ConfigFile :: parse_toml ( file_contents) . unwrap ( ) ;
77+ let mut root_dir = PathBuf :: from ( std:: env:: current_dir ( ) . unwrap ( ) ) ;
78+
79+ root_dir. push ( "./fixtures" ) ;
6080
6181 assert_eq ! ( config. host, host) ;
6282 assert_eq ! ( config. port, port) ;
63- assert_eq ! ( config. root_dir. unwrap( ) , root_dir) ;
6483 assert_eq ! ( config. verbose, Some ( true ) ) ;
84+ assert_eq ! ( config. root_dir, Some ( root_dir) ) ;
6585 }
6686
6787 #[ test]
@@ -81,7 +101,6 @@ mod tests {
81101 host = "192.168.0.1"
82102 port = 7878
83103 verbose = false
84- root_dir = "~/Desktop"
85104
86105 [tls]
87106 cert = "cert_123.pem"
@@ -90,7 +109,7 @@ mod tests {
90109 "# ;
91110 let host = IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 0 , 1 ) ) ;
92111 let port = 7878 ;
93- let root_dir = PathBuf :: from_str ( "~/Desktop" ) . unwrap ( ) ;
112+ let root_dir = Some ( std :: env :: current_dir ( ) . unwrap ( ) ) ;
94113 let tls = TlsConfigFile {
95114 cert : PathBuf :: from_str ( "cert_123.pem" ) . unwrap ( ) ,
96115 key : PathBuf :: from_str ( "key_123.pem" ) . unwrap ( ) ,
@@ -100,7 +119,7 @@ mod tests {
100119
101120 assert_eq ! ( config. host, host) ;
102121 assert_eq ! ( config. port, port) ;
103- assert_eq ! ( config. root_dir. unwrap ( ) , root_dir) ;
122+ assert_eq ! ( config. root_dir, root_dir) ;
104123 assert_eq ! ( config. tls. unwrap( ) , tls) ;
105124 assert_eq ! ( config. verbose, Some ( false ) ) ;
106125 }
@@ -110,7 +129,6 @@ mod tests {
110129 let file_contents = r#"
111130 host = "192.168.0.1"
112131 port = 7878
113- root_dir = "~/Desktop"
114132
115133 [tls]
116134 cert = "cert_123.pem"
@@ -119,7 +137,7 @@ mod tests {
119137 "# ;
120138 let host = IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 0 , 1 ) ) ;
121139 let port = 7878 ;
122- let root_dir = PathBuf :: from_str ( "~/Desktop" ) . unwrap ( ) ;
140+ let root_dir = Some ( std :: env :: current_dir ( ) . unwrap ( ) ) ;
123141 let tls = TlsConfigFile {
124142 cert : PathBuf :: from_str ( "cert_123.pem" ) . unwrap ( ) ,
125143 key : PathBuf :: from_str ( "key_123.pem" ) . unwrap ( ) ,
@@ -129,7 +147,7 @@ mod tests {
129147
130148 assert_eq ! ( config. host, host) ;
131149 assert_eq ! ( config. port, port) ;
132- assert_eq ! ( config. root_dir. unwrap ( ) , root_dir) ;
150+ assert_eq ! ( config. root_dir, root_dir) ;
133151 assert_eq ! ( config. tls. unwrap( ) , tls) ;
134152 }
135153
@@ -168,9 +186,11 @@ mod tests {
168186 request_method : None ,
169187 } ;
170188 let config = ConfigFile :: parse_toml ( file_contents) . unwrap ( ) ;
189+ let root_dir = Some ( std:: env:: current_dir ( ) . unwrap ( ) ) ;
171190
172191 assert_eq ! ( config. host, host) ;
173192 assert_eq ! ( config. port, port) ;
193+ assert_eq ! ( config. root_dir, root_dir) ;
174194 assert_eq ! ( config. cors. unwrap( ) , cors) ;
175195 }
176196
@@ -192,6 +212,7 @@ mod tests {
192212 "# ;
193213 let host = IpAddr :: V4 ( Ipv4Addr :: new ( 0 , 0 , 0 , 0 ) ) ;
194214 let port = 8080 ;
215+ let root_dir = Some ( std:: env:: current_dir ( ) . unwrap ( ) ) ;
195216 let cors = CorsConfigFile {
196217 allow_credentials : true ,
197218 allow_headers : Some ( vec ! [
@@ -216,6 +237,7 @@ mod tests {
216237
217238 assert_eq ! ( config. host, host) ;
218239 assert_eq ! ( config. port, port) ;
240+ assert_eq ! ( config. root_dir, root_dir) ;
219241 assert_eq ! ( config. cors. unwrap( ) , cors) ;
220242 }
221243}
0 commit comments