@@ -5,14 +5,18 @@ use std::{io, path::Path};
55
66use crate :: {
77 lockfile:: { LockfileMismatchError , LockfileMismatchHandler } ,
8- spirv_builder:: SpirvBuilder ,
8+ spirv_builder:: { CompileResult , SpirvBuilder , SpirvBuilderError } ,
99 spirv_cache:: {
1010 command:: CommandExecError ,
1111 install:: { Install , InstallError , InstallParams , InstalledBackend } ,
1212 toolchain:: HaltToolchainInstallation ,
13+ user_output,
1314 } ,
1415} ;
1516
17+ #[ cfg( feature = "watch" ) ]
18+ use crate :: spirv_builder:: { AcceptFirstCompile , Watch } ;
19+
1620/// Creates shader crate builder, allowing to modify install and build parameters separately.
1721///
1822/// # Errors
@@ -24,14 +28,14 @@ use crate::{
2428/// * there is a lockfile version mismatch that cannot be resolved automatically.
2529#[ inline]
2630#[ expect( clippy:: unreachable, reason = "target was already set" ) ]
27- pub fn shader_crate_builder < P , S , E , T , C , W > (
31+ pub fn make_shader_crate_builder < P , S , E , T , C , W > (
2832 shader_crate : P ,
2933 target : S ,
3034 mut build : SpirvBuilder ,
3135 install : InstallParams ,
3236 writer : W ,
3337 halt_toolchain_installation : HaltToolchainInstallation < T , C > ,
34- ) -> Result < ShaderCrateBuilder , MakeShaderBuilderError < E > >
38+ ) -> Result < ShaderCrateBuilder , MakeShaderCrateBuilderError < E > >
3539where
3640 P : AsRef < Path > ,
3741 S : Into < String > ,
@@ -78,10 +82,57 @@ pub struct ShaderCrateBuilder {
7882 pub lockfile_mismatch_handler : LockfileMismatchHandler ,
7983}
8084
85+ impl ShaderCrateBuilder {
86+ /// Builds the shader crate using the configured [`SpirvBuilder`].
87+ ///
88+ /// # Errors
89+ ///
90+ /// Returns an error if building the shader crate failed.
91+ #[ inline]
92+ pub fn build < W > ( & self , writer : W ) -> Result < CompileResult , ShaderCrateBuildError >
93+ where
94+ W : io:: Write ,
95+ {
96+ let shader_crate = self . installed_backend_args . shader_crate . display ( ) ;
97+ user_output ! ( writer, "Compiling shaders at {shader_crate}...\n " ) ?;
98+
99+ let result = self . builder . build ( ) ?;
100+ Ok ( result)
101+ }
102+
103+ /// Watches the shader crate for changes using the configured [`SpirvBuilder`].
104+ ///
105+ /// Calls `on_compilation_finishes` after each successful compilation.
106+ ///
107+ /// # Errors
108+ ///
109+ /// Returns an error if watching shader crate for changes failed.
110+ #[ cfg( feature = "watch" ) ]
111+ #[ inline]
112+ pub fn watch < W , T , F > (
113+ & self ,
114+ writer : W ,
115+ on_compilation_finishes : F ,
116+ ) -> Result < Watch < T > , ShaderCrateBuildError >
117+ where
118+ W : io:: Write ,
119+ F : FnMut ( CompileResult , Option < AcceptFirstCompile < ' _ , T > > ) + Send + ' static ,
120+ {
121+ let shader_crate = self . installed_backend_args . shader_crate . display ( ) ;
122+ user_output ! (
123+ writer,
124+ "Watching shaders for changes at {shader_crate}...\n "
125+ ) ?;
126+
127+ let watch = self . builder . watch ( on_compilation_finishes) ?;
128+ Ok ( watch)
129+ }
130+ }
131+
81132/// An error indicating what went wrong when creating a [`ShaderCrateBuilder`].
82133#[ derive( Debug , thiserror:: Error ) ]
83134#[ non_exhaustive]
84- pub enum MakeShaderBuilderError < E > {
135+ pub enum MakeShaderCrateBuilderError < E = CommandExecError > {
85136 /// The given shader crate path is not valid.
86137 #[ error( "shader crate path is not valid: {0}" ) ]
87138 InvalidCratePath ( #[ from] io:: Error ) ,
@@ -92,3 +143,15 @@ pub enum MakeShaderBuilderError<E> {
92143 #[ error( transparent) ]
93144 LockfileMismatch ( #[ from] LockfileMismatchError ) ,
94145}
146+
147+ /// An error indicating what went wrong when building the shader crate.
148+ #[ derive( Debug , thiserror:: Error ) ]
149+ #[ non_exhaustive]
150+ pub enum ShaderCrateBuildError {
151+ /// Failed to write user output.
152+ #[ error( "failed to write user output: {0}" ) ]
153+ IoWrite ( #[ from] io:: Error ) ,
154+ /// Failed to build shader crate.
155+ #[ error( "failed to build shader crate: {0}" ) ]
156+ Build ( #[ from] SpirvBuilderError ) ,
157+ }
0 commit comments