@@ -52,19 +52,32 @@ config_struct!(
5252 pub struct GlobOutput {
5353 /// The glob pattern.
5454 pub glob: GlobPath ,
55+
56+ /// Mark the file as optional instead of failing with
57+ /// an error after running a task and the output doesn't exist.
58+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
59+ pub optional: Option <bool >,
5560 }
5661) ;
5762
5863generate_io_glob_methods ! ( GlobOutput ) ;
5964
6065impl GlobOutput {
6166 pub fn from_uri ( uri : Uri ) -> Result < Self , ParseError > {
62- let output = Self {
67+ let mut output = Self {
6368 glob : GlobPath :: parse ( uri. path . replace ( "__QM__" , "?" ) ) ?,
69+ optional : None ,
6470 } ;
6571
66- if let Some ( ( key, _) ) = uri. query . into_iter ( ) . next ( ) {
67- return Err ( ParseError :: new ( format ! ( "unknown glob field `{key}`" ) ) ) ;
72+ for ( key, value) in uri. query {
73+ match key. as_str ( ) {
74+ "optional" => {
75+ output. optional = Some ( parse_bool_field ( & key, & value) ?) ;
76+ }
77+ _ => {
78+ return Err ( ParseError :: new ( format ! ( "unknown glob field `{key}`" ) ) ) ;
79+ }
80+ } ;
6881 }
6982
7083 Ok ( output)
@@ -114,6 +127,14 @@ impl Output {
114127 pub fn is_glob ( & self ) -> bool {
115128 matches ! ( self , Self :: Glob ( _) )
116129 }
130+
131+ pub fn is_optional ( & self ) -> bool {
132+ match self {
133+ Output :: File ( value) => value. optional . unwrap_or_default ( ) ,
134+ Output :: Glob ( value) => value. optional . unwrap_or_default ( ) ,
135+ _ => false ,
136+ }
137+ }
117138}
118139
119140impl FromStr for Output {
0 commit comments