@@ -251,6 +251,47 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
251
251
Ok ( bytes)
252
252
}
253
253
254
+ /// Read the entire contents of a file into a string.
255
+ ///
256
+ /// This is a convenience function for using [`File::open`] and [`read_to_string`]
257
+ /// with fewer imports and without an intermediate variable.
258
+ ///
259
+ /// [`File::open`]: struct.File.html#method.open
260
+ /// [`read_to_string`]: ../io/trait.Read.html#method.read_to_string
261
+ ///
262
+ /// # Errors
263
+ ///
264
+ /// This function will return an error if `path` does not already exist.
265
+ /// Other errors may also be returned according to [`OpenOptions::open`].
266
+ ///
267
+ /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
268
+ ///
269
+ /// It will also return an error if it encounters while reading an error
270
+ /// of a kind other than [`ErrorKind::Interrupted`],
271
+ /// or if the contents of the file are not valid UTF-8.
272
+ ///
273
+ /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
274
+ ///
275
+ /// # Examples
276
+ ///
277
+ /// ```no_run
278
+ /// #![feature(fs_read_write)]
279
+ ///
280
+ /// use std::fs;
281
+ /// use std::net::SocketAddr;
282
+ ///
283
+ /// # fn foo() -> Result<(), Box<std::error::Error + 'static>> {
284
+ /// let foo: SocketAddr = fs::read_utf8("address.txt")?.parse()?;
285
+ /// # Ok(())
286
+ /// # }
287
+ /// ```
288
+ #[ unstable( feature = "fs_read_write" , issue = /* FIXME */ "0" ) ]
289
+ pub fn read_utf8 < P : AsRef < Path > > ( path : P ) -> io:: Result < String > {
290
+ let mut string = String :: new ( ) ;
291
+ File :: open ( path) ?. read_to_string ( & mut string) ?;
292
+ Ok ( string)
293
+ }
294
+
254
295
/// Write a slice as the entire contents of a file.
255
296
///
256
297
/// This function will create a file if it does not exist,
@@ -1980,7 +2021,9 @@ mod tests {
1980
2021
) }
1981
2022
1982
2023
#[ cfg( unix) ]
1983
- macro_rules! error { ( $e: expr, $s: expr) => (
2024
+ macro_rules! error { ( $e: expr, $s: expr) => ( error_contains!( $e, $s) ) }
2025
+
2026
+ macro_rules! error_contains { ( $e: expr, $s: expr) => (
1984
2027
match $e {
1985
2028
Ok ( _) => panic!( "Unexpected success. Should've been: {:?}" , $s) ,
1986
2029
Err ( ref err) => assert!( err. to_string( ) . contains( $s) ,
@@ -2999,6 +3042,15 @@ mod tests {
2999
3042
check ! ( fs:: write( & tmpdir. join( "test" ) , & bytes) ) ;
3000
3043
let v = check ! ( fs:: read( & tmpdir. join( "test" ) ) ) ;
3001
3044
assert ! ( v == & bytes[ ..] ) ;
3045
+
3046
+ check ! ( fs:: write( & tmpdir. join( "not-utf8" ) , & [ 0xFF ] ) ) ;
3047
+ error_contains ! ( fs:: read_utf8( & tmpdir. join( "not-utf8" ) ) ,
3048
+ "stream did not contain valid UTF-8" ) ;
3049
+
3050
+ let s = "𐁁𐀓𐀠𐀴𐀍" ;
3051
+ check ! ( fs:: write( & tmpdir. join( "utf8" ) , s. as_bytes( ) ) ) ;
3052
+ let string = check ! ( fs:: read_utf8( & tmpdir. join( "utf8" ) ) ) ;
3053
+ assert_eq ! ( string, s) ;
3002
3054
}
3003
3055
3004
3056
#[ test]
0 commit comments