hugr_core/extension/
const_fold.rs1use std::fmt::Formatter;
2
3use std::fmt::Debug;
4
5use crate::ops::Value;
6use crate::types::TypeArg;
7
8use crate::IncomingPort;
9use crate::OutgoingPort;
10
11use crate::ops;
12
13pub type ConstFoldResult = Option<Vec<(OutgoingPort, ops::Value)>>;
17
18pub fn fold_out_row(consts: impl IntoIterator<Item = Value>) -> ConstFoldResult {
20 let vec = consts
21 .into_iter()
22 .enumerate()
23 .map(|(i, c)| (i.into(), c))
24 .collect();
25 Some(vec)
26}
27
28pub trait ConstFold: Send + Sync {
30 fn fold(
34 &self,
35 type_args: &[TypeArg],
36 consts: &[(crate::IncomingPort, crate::ops::Value)],
37 ) -> ConstFoldResult;
38}
39
40impl Debug for Box<dyn ConstFold> {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 write!(f, "<custom constant folding>")
43 }
44}
45
46impl<T> ConstFold for T
49where
50 T: Fn(&[(crate::IncomingPort, crate::ops::Value)]) -> ConstFoldResult + Send + Sync,
51{
52 fn fold(
53 &self,
54 _type_args: &[TypeArg],
55 consts: &[(crate::IncomingPort, crate::ops::Value)],
56 ) -> ConstFoldResult {
57 self(consts)
58 }
59}
60
61type FoldFn = dyn Fn(&[TypeArg], &[(IncomingPort, Value)]) -> ConstFoldResult + Send + Sync;
62
63pub struct Folder {
65 pub folder: Box<FoldFn>,
67}
68
69impl ConstFold for Folder {
70 fn fold(&self, type_args: &[TypeArg], consts: &[(IncomingPort, Value)]) -> ConstFoldResult {
71 (self.folder)(type_args, consts)
72 }
73}