spirq/
inspect.rs

1//! Inspect SPIR-V function parsing.
2use crate::{error::Result, parse::Instr, reflect::ReflectIntermediate};
3
4pub trait Inspector {
5    /// For each instruction iterated in a function parse, the inspector receive
6    /// the instruction after the reflector finishes processing it.
7    fn inspect<'a>(&mut self, itm: &mut ReflectIntermediate<'a>, instr: &Instr) -> Result<()>;
8
9    /// Chain two inspectors together. The second inspector will be called after
10    /// the first one.
11    fn chain<'a, I2: Inspector>(&'a mut self, second: &'a mut I2) -> Chain<Self, I2>
12    where
13        Self: Sized,
14    {
15        Chain {
16            first: self,
17            second: second,
18        }
19    }
20}
21
22/// Inspector that calls a function wrapped up in it.
23pub(crate) struct FnInspector<F: FnMut(&mut ReflectIntermediate<'_>, &Instr)>(pub F);
24impl<F: FnMut(&mut ReflectIntermediate<'_>, &Instr)> Inspector for FnInspector<F> {
25    fn inspect<'a>(&mut self, itm: &mut ReflectIntermediate<'a>, instr: &Instr) -> Result<()> {
26        Ok(self.0(itm, instr))
27    }
28}
29
30pub struct Chain<'a, I1: Inspector, I2: Inspector> {
31    first: &'a mut I1,
32    second: &'a mut I2,
33}
34impl<I1: Inspector, I2: Inspector> Inspector for Chain<'_, I1, I2> {
35    fn inspect<'a>(&mut self, itm: &mut ReflectIntermediate<'a>, instr: &Instr) -> Result<()> {
36        self.first.inspect(itm, instr)?;
37        self.second.inspect(itm, instr)
38    }
39}