openvm_stark_backend/
any_air.rs1use std::{
4 any::{type_name, Any},
5 sync::Arc,
6};
7
8pub use p3_air::BaseAirWithPublicValues;
10use p3_air::{Air, BaseAir};
11
12use crate::{
13 air_builders::{debug::DebugConstraintBuilder, symbolic::SymbolicRapBuilder},
14 config::StarkProtocolConfig,
15};
16
17pub trait PartitionedBaseAir<F>: BaseAir<F> {
19 fn cached_main_widths(&self) -> Vec<usize> {
21 vec![]
22 }
23 fn common_main_width(&self) -> usize {
25 self.width()
26 }
27}
28
29pub type AirRef<SC> = Arc<dyn AnyAir<SC>>;
32
33pub trait AnyAir<SC: StarkProtocolConfig>:
37Air<SymbolicRapBuilder<SC::F>> + for<'a> Air<DebugConstraintBuilder<'a, SC>> + BaseAirWithPublicValues<SC::F>
40 + PartitionedBaseAir<SC::F>
41 + Send + Sync
42{
43 fn as_any(&self) -> &dyn Any;
44 fn name(&self) -> String;
46}
47
48impl<SC, T> AnyAir<SC> for T
49where
50 SC: StarkProtocolConfig,
51 T: Air<SymbolicRapBuilder<SC::F>>
52 + for<'a> Air<DebugConstraintBuilder<'a, SC>>
53 + BaseAirWithPublicValues<SC::F>
54 + PartitionedBaseAir<SC::F>
55 + Send
56 + Sync
57 + 'static,
58{
59 fn as_any(&self) -> &dyn Any {
60 self
61 }
62
63 fn name(&self) -> String {
64 get_air_name(self)
65 }
66}
67
68pub fn get_air_name<T>(_rap: &T) -> String {
70 let full_name = type_name::<T>().to_string();
71 if let Some((main_part, generics_part)) = full_name.split_once('<') {
73 let main_type = main_part.split("::").last().unwrap_or("");
75
76 let generics: Vec<String> = generics_part
79 .trim_end_matches('>')
80 .split(", ")
81 .map(|generic| {
82 generic.split("::").last().unwrap_or("").to_string()
84 })
85 .collect();
86
87 format!("{}<{}>", main_type, generics.join(", "))
89 } else {
90 full_name.split("::").last().unwrap_or("").to_string()
92 }
93}