@@ -4,15 +4,25 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr};
44
55#[ derive( Clone , Debug ) ]
66pub enum VariableSource {
7+ /// The value of the given variable name is the given string
78 Literal ( String , String ) ,
9+ /// The value of the given variable name is the content of the given file (as a string)
10+ FileContent ( String , PathBuf ) ,
11+ /// The file contains a map of variable names to (string) values
812 JsonFile ( PathBuf ) ,
13+ /// The file contains a map of variable names to (string) values
914 TomlFile ( PathBuf ) ,
1015}
1116
1217impl VariableSource {
1318 pub fn get_variables ( & self ) -> anyhow:: Result < HashMap < String , String > > {
1419 match self {
1520 VariableSource :: Literal ( key, val) => Ok ( [ ( key. to_string ( ) , val. to_string ( ) ) ] . into ( ) ) ,
21+ VariableSource :: FileContent ( key, path) => {
22+ let val = std:: fs:: read_to_string ( path)
23+ . with_context ( || format ! ( "Failed to read {}." , quoted_path( path) ) ) ?;
24+ Ok ( [ ( key. to_string ( ) , val) ] . into ( ) )
25+ }
1626 VariableSource :: JsonFile ( path) => {
1727 let json_bytes = std:: fs:: read ( path)
1828 . with_context ( || format ! ( "Failed to read {}." , quoted_path( path) ) ) ?;
@@ -43,7 +53,14 @@ impl FromStr for VariableSource {
4353 _ => bail ! ( "variable files must end in .json or .toml" ) ,
4454 }
4555 } else if let Some ( ( key, val) ) = s. split_once ( '=' ) {
46- Ok ( VariableSource :: Literal ( key. to_string ( ) , val. to_string ( ) ) )
56+ if let Some ( path) = val. strip_prefix ( '@' ) {
57+ Ok ( VariableSource :: FileContent (
58+ key. to_string ( ) ,
59+ PathBuf :: from ( path) ,
60+ ) )
61+ } else {
62+ Ok ( VariableSource :: Literal ( key. to_string ( ) , val. to_string ( ) ) )
63+ }
4764 } else {
4865 bail ! ( "variables must be in the form 'key=value' or '@file'" )
4966 }
@@ -66,6 +83,14 @@ mod tests {
6683 Ok ( other) => panic ! ( "wrong variant {other:?}" ) ,
6784 Err ( err) => panic ! ( "{err:?}" ) ,
6885 }
86+ match "[email protected] " . parse ( ) { 87+ Ok ( VariableSource :: FileContent ( key, path) ) => {
88+ assert_eq ! ( key, "k" ) ;
89+ assert_eq ! ( path, PathBuf :: from( "v.txt" ) ) ;
90+ }
91+ Ok ( other) => panic ! ( "wrong variant {other:?}" ) ,
92+ Err ( err) => panic ! ( "{err:?}" ) ,
93+ }
6994 match "@file.json" . parse ( ) {
7095 Ok ( VariableSource :: JsonFile ( _) ) => { }
7196 Ok ( other) => panic ! ( "wrong variant {other:?}" ) ,
@@ -93,6 +118,17 @@ mod tests {
93118 assert_eq ! ( vars[ "k" ] , "v" ) ;
94119 }
95120
121+ #[ test]
122+ fn file_content_get_variables ( ) {
123+ let mut file = tempfile:: NamedTempFile :: with_suffix ( ".txt" ) . unwrap ( ) ;
124+ file. write_all ( br#"sausage time!"# ) . unwrap ( ) ;
125+ let path = file. into_temp_path ( ) ;
126+ let vars = VariableSource :: FileContent ( "k" . to_string ( ) , path. to_path_buf ( ) )
127+ . get_variables ( )
128+ . unwrap ( ) ;
129+ assert_eq ! ( vars[ "k" ] , "sausage time!" ) ;
130+ }
131+
96132 #[ test]
97133 fn json_get_variables ( ) {
98134 let mut json_file = tempfile:: NamedTempFile :: with_suffix ( ".json" ) . unwrap ( ) ;
0 commit comments