7
7
//!
8
8
//! See the [reference][`_reference`] for the full `sqlx.toml` file.
9
9
10
+ use std:: error:: Error ;
10
11
use std:: fmt:: Debug ;
11
12
use std:: io;
12
13
use std:: path:: { Path , PathBuf } ;
@@ -23,15 +24,16 @@ pub mod common;
23
24
/// Configuration for the `query!()` family of macros.
24
25
///
25
26
/// See [`macros::Config`] for details.
26
- #[ cfg( feature = "config-macros" ) ]
27
27
pub mod macros;
28
28
29
29
/// Configuration for migrations when executed using `sqlx::migrate!()` or through `sqlx-cli`.
30
30
///
31
31
/// See [`migrate::Config`] for details.
32
- #[ cfg( feature = "config-migrate" ) ]
33
32
pub mod migrate;
34
33
34
+ #[ cfg( feature = "sqlx-toml" ) ]
35
+ mod sqlx_toml;
36
+
35
37
/// Reference for `sqlx.toml` files
36
38
///
37
39
/// Source: `sqlx-core/src/config/reference.toml`
@@ -41,11 +43,12 @@ pub mod migrate;
41
43
/// ```
42
44
pub mod _reference { }
43
45
44
- #[ cfg( test) ]
46
+ #[ cfg( all ( test, feature = "sqlx-toml" ) ) ]
45
47
mod tests;
46
48
47
49
/// The parsed structure of a `sqlx.toml` file.
48
- #[ derive( Debug , Default , serde:: Deserialize ) ]
50
+ #[ derive( Debug , Default ) ]
51
+ #[ cfg_attr( feature = "sqlx-toml" , derive( serde:: Deserialize ) ) ]
49
52
pub struct Config {
50
53
/// Configuration shared by multiple components.
51
54
///
@@ -55,21 +58,11 @@ pub struct Config {
55
58
/// Configuration for the `query!()` family of macros.
56
59
///
57
60
/// See [`macros::Config`] for details.
58
- #[ cfg_attr(
59
- docsrs,
60
- doc( cfg( any( feature = "config-all" , feature = "config-macros" ) ) )
61
- ) ]
62
- #[ cfg( feature = "config-macros" ) ]
63
61
pub macros : macros:: Config ,
64
62
65
63
/// Configuration for migrations when executed using `sqlx::migrate!()` or through `sqlx-cli`.
66
64
///
67
65
/// See [`migrate::Config`] for details.
68
- #[ cfg_attr(
69
- docsrs,
70
- doc( cfg( any( feature = "config-all" , feature = "config-migrate" ) ) )
71
- ) ]
72
- #[ cfg( feature = "config-migrate" ) ]
73
66
pub migrate : migrate:: Config ,
74
67
}
75
68
@@ -90,13 +83,17 @@ pub enum ConfigError {
90
83
std:: env:: VarError ,
91
84
) ,
92
85
86
+ /// No configuration file was found. Not necessarily fatal.
87
+ #[ error( "config file {path:?} not found" ) ]
88
+ NotFound {
89
+ path : PathBuf ,
90
+ } ,
91
+
93
92
/// An I/O error occurred while attempting to read the config file at `path`.
94
93
///
95
- /// This includes [`io::ErrorKind::NotFound`].
96
- ///
97
- /// [`Self::not_found_path()`] will return the path if the file was not found.
94
+ /// If the error is [`io::ErrorKind::NotFound`], [`Self::NotFound`] is returned instead.
98
95
#[ error( "error reading config file {path:?}" ) ]
99
- Read {
96
+ Io {
100
97
path : PathBuf ,
101
98
#[ source]
102
99
error : io:: Error ,
@@ -108,19 +105,36 @@ pub enum ConfigError {
108
105
#[ error( "error parsing config file {path:?}" ) ]
109
106
Parse {
110
107
path : PathBuf ,
108
+ /// Type-erased [`toml::de::Error`].
111
109
#[ source]
112
- error : toml:: de:: Error ,
110
+ error : Box < dyn Error + Send + Sync + ' static > ,
111
+ } ,
112
+
113
+ /// A `sqlx.toml` file was found or specified, but the `sqlx-toml` feature is not enabled.
114
+ #[ error( "SQLx found config file at {path:?} but the `sqlx-toml` feature was not enabled" ) ]
115
+ ParseDisabled {
116
+ path : PathBuf
113
117
} ,
114
118
}
115
119
116
120
impl ConfigError {
121
+ /// Create a [`ConfigError`] from a [`std::io::Error`].
122
+ ///
123
+ /// Maps to either `NotFound` or `Io`.
124
+ pub fn from_io ( path : PathBuf , error : io:: Error ) -> Self {
125
+ if error. kind ( ) == io:: ErrorKind :: NotFound {
126
+ Self :: NotFound { path }
127
+ } else {
128
+ Self :: Io { path, error }
129
+ }
130
+ }
131
+
117
132
/// If this error means the file was not found, return the path that was attempted.
118
133
pub fn not_found_path ( & self ) -> Option < & Path > {
119
- match self {
120
- ConfigError :: Read { path, error } if error. kind ( ) == io:: ErrorKind :: NotFound => {
121
- Some ( path)
122
- }
123
- _ => None ,
134
+ if let Self :: NotFound { path } = self {
135
+ Some ( path)
136
+ } else {
137
+ None
124
138
}
125
139
}
126
140
}
@@ -140,14 +154,22 @@ impl Config {
140
154
/// If the file exists but an unrecoverable error was encountered while parsing it.
141
155
pub fn from_crate ( ) -> & ' static Self {
142
156
Self :: try_from_crate ( ) . unwrap_or_else ( |e| {
143
- if let Some ( path) = e. not_found_path ( ) {
144
- // Non-fatal
145
- tracing:: debug!( "Not reading config, file {path:?} not found (error: {e})" ) ;
146
- CACHE . get_or_init ( Config :: default)
147
- } else {
157
+ match e {
158
+ ConfigError :: NotFound { path } => {
159
+ // Non-fatal
160
+ tracing:: debug!( "Not reading config, file {path:?} not found (error: {e})" ) ;
161
+ CACHE . get_or_init ( Config :: default)
162
+ }
163
+ // FATAL ERRORS BELOW:
148
164
// In the case of migrations,
149
165
// we can't proceed with defaults as they may be completely wrong.
150
- panic ! ( "failed to read sqlx config: {e}" )
166
+ e @ ConfigError :: ParseDisabled { .. } => {
167
+ // Only returned if the file exists but the feature is not enabled.
168
+ panic ! ( "{e}" )
169
+ }
170
+ e => {
171
+ panic ! ( "failed to read sqlx config: {e}" )
172
+ }
151
173
}
152
174
} )
153
175
}
@@ -188,12 +210,13 @@ impl Config {
188
210
} )
189
211
}
190
212
213
+ #[ cfg( feature = "sqlx-toml" ) ]
191
214
fn read_from ( path : PathBuf ) -> Result < Self , ConfigError > {
192
215
// The `toml` crate doesn't provide an incremental reader.
193
216
let toml_s = match std:: fs:: read_to_string ( & path) {
194
217
Ok ( toml) => toml,
195
218
Err ( error) => {
196
- return Err ( ConfigError :: Read { path, error } ) ;
219
+ return Err ( ConfigError :: from_io ( path, error) ) ;
197
220
}
198
221
} ;
199
222
@@ -203,4 +226,13 @@ impl Config {
203
226
204
227
toml:: from_str ( & toml_s) . map_err ( |error| ConfigError :: Parse { path, error } )
205
228
}
229
+
230
+ #[ cfg( not( feature = "sqlx-toml" ) ) ]
231
+ fn read_from ( path : PathBuf ) -> Result < Self , ConfigError > {
232
+ match path. try_exists ( ) {
233
+ Ok ( true ) => Err ( ConfigError :: ParseDisabled { path } ) ,
234
+ Ok ( false ) => Err ( ConfigError :: NotFound { path } ) ,
235
+ Err ( e) => Err ( ConfigError :: from_io ( path, e) )
236
+ }
237
+ }
206
238
}
0 commit comments