cairo_lang_filesystem/
flag.rs1use cairo_lang_utils::Intern;
2use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
3use salsa::{Database, Setter};
4use serde::{Deserialize, Serialize};
5
6use crate::db::files_group_input;
7use crate::ids::{FlagId, FlagLongId};
8
9#[derive(PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize, Hash, salsa::Update)]
11pub enum Flag {
12 AddWithdrawGas(bool),
17 NumericMatchOptimizationMinArmsThreshold(usize),
18 PanicBacktrace(bool),
22 UnsafePanic(bool),
26 FutureSierra(bool),
30}
31impl Flag {
32 pub const ADD_WITHDRAW_GAS: &'static str = "add_withdraw_gas";
33 pub const NUMERIC_MATCH_OPTIMIZATION_MIN_ARMS_THRESHOLD: &'static str =
34 "numeric_match_optimization_min_arms_threshold";
35 pub const PANIC_BACKTRACE: &'static str = "panic_backtrace";
36 pub const UNSAFE_PANIC: &'static str = "unsafe_panic";
37 pub const FUTURE_SIERRA: &'static str = "future_sierra";
38}
39
40macro_rules! extract_flag_value {
44 ($db:ident, $flag:ident, $variant:ident) => {{
45 let flag = FlagId::new($db, FlagLongId(Flag::$flag.into()));
46 match $db.get_flag(flag) {
47 None => None,
48 Some(Flag::$variant(value)) => Some(value),
49 Some(other) => panic!("Unexpected flag variant for `{}`: {other:?}", Flag::$flag),
50 }
51 }};
52}
53
54#[salsa::tracked]
56fn flag_add_withdraw_gas(db: &dyn Database) -> bool {
57 extract_flag_value!(db, ADD_WITHDRAW_GAS, AddWithdrawGas).unwrap_or(true)
58}
59
60#[salsa::tracked]
63fn flag_numeric_match_optimization_min_arms_threshold(db: &dyn salsa::Database) -> Option<usize> {
64 extract_flag_value!(
65 db,
66 NUMERIC_MATCH_OPTIMIZATION_MIN_ARMS_THRESHOLD,
67 NumericMatchOptimizationMinArmsThreshold
68 )
69}
70
71#[salsa::tracked]
73fn flag_panic_backtrace(db: &dyn salsa::Database) -> bool {
74 extract_flag_value!(db, PANIC_BACKTRACE, PanicBacktrace).unwrap_or_default()
75}
76
77#[salsa::tracked]
79fn flag_unsafe_panic(db: &dyn salsa::Database) -> bool {
80 extract_flag_value!(db, UNSAFE_PANIC, UnsafePanic).unwrap_or_default()
81}
82
83#[salsa::tracked]
85fn flag_future_sierra(db: &dyn salsa::Database) -> bool {
86 extract_flag_value!(db, FUTURE_SIERRA, FutureSierra).unwrap_or_default()
87}
88
89#[salsa::tracked(returns(ref))]
90pub fn flags<'db>(db: &'db dyn Database) -> OrderedHashMap<FlagId<'db>, Flag> {
91 let inp = files_group_input(db).flags(db).as_ref().expect("flags is not set");
92 inp.iter().map(|(flag_id, flag)| (flag_id.clone().intern(db), *flag)).collect()
93}
94
95#[salsa::tracked]
97fn get_flag<'db>(db: &'db dyn Database, id: FlagId<'db>) -> Option<Flag> {
98 db.flags().get(&id).copied()
99}
100
101pub trait FlagsGroup: Database {
102 fn flags<'db>(&'db self) -> &'db OrderedHashMap<FlagId<'db>, Flag> {
104 flags(self.as_dyn_database())
105 }
106 fn get_flag<'db>(&'db self, id: FlagId<'db>) -> Option<Flag> {
108 get_flag(self.as_dyn_database(), id)
109 }
110
111 fn set_flag(&mut self, flag: FlagLongId, value: Option<Flag>) {
113 let db_ref = self.as_dyn_database();
114 let mut flags = files_group_input(db_ref).flags(db_ref).clone().unwrap();
115 match value {
116 Some(value) => flags.insert(flag, value),
117 None => flags.swap_remove(&flag),
118 };
119 files_group_input(db_ref).set_flags(self).to(Some(flags));
120 }
121 fn flag_add_withdraw_gas(&self) -> bool {
123 flag_add_withdraw_gas(self.as_dyn_database())
124 }
125 fn flag_numeric_match_optimization_min_arms_threshold(&self) -> Option<usize> {
127 flag_numeric_match_optimization_min_arms_threshold(self.as_dyn_database())
128 }
129 fn flag_panic_backtrace(&self) -> bool {
131 flag_panic_backtrace(self.as_dyn_database())
132 }
133 fn flag_unsafe_panic(&self) -> bool {
135 flag_unsafe_panic(self.as_dyn_database())
136 }
137 fn flag_future_sierra(&self) -> bool {
139 flag_future_sierra(self.as_dyn_database())
140 }
141}
142impl<T: Database + ?Sized> FlagsGroup for T {}