1#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(not(feature = "std"))]
6extern crate alloc;
7
8pub use ::smol_str;
11
12pub mod bigint;
13pub mod byte_array;
14pub mod casts;
15pub mod collection_arithmetics;
16pub mod deque;
17pub mod extract_matches;
18#[cfg(feature = "std")]
19pub mod graph_algos;
20#[cfg(feature = "std")]
21pub mod heap_size;
22pub mod iterators;
23#[cfg(feature = "tracing")]
24pub mod logging;
25pub mod ordered_hash_map;
26pub mod ordered_hash_set;
27#[cfg(feature = "std")]
28pub mod small_ordered_map;
29pub mod unordered_hash_map;
30pub mod unordered_hash_set;
31
32#[cfg(feature = "std")]
33pub use heap_size::HeapSize;
34
35pub trait OptionFrom<T>: Sized {
37 fn option_from(other: T) -> Option<Self>;
38}
39
40pub trait OptionHelper {
42 fn on_none<F: FnOnce()>(self, f: F) -> Self;
43}
44impl<T> OptionHelper for Option<T> {
45 fn on_none<F: FnOnce()>(self, f: F) -> Self {
46 if self.is_none() {
47 f();
48 }
49 self
50 }
51}
52
53#[cfg(feature = "std")]
55pub trait CloneableDatabase: salsa::Database + Send {
56 fn dyn_clone(&self) -> Box<dyn CloneableDatabase>;
58}
59
60#[cfg(feature = "std")]
62impl Clone for Box<dyn CloneableDatabase> {
63 fn clone(&self) -> Self {
64 self.dyn_clone()
65 }
66}
67
68#[cfg(feature = "std")]
69pub trait Intern<'db, Target> {
70 fn intern(self, db: &'db dyn salsa::Database) -> Target;
71}
72
73#[macro_export]
83macro_rules! define_short_id {
84 ($short_id:ident, $long_id:path) => {
85 #[cairo_lang_proc_macros::interned(revisions = usize::MAX)]
87 pub struct $short_id<'db> {
88 #[returns(ref)]
89 pub long: $long_id,
90 }
91
92 impl<'db> std::fmt::Debug for $short_id<'db> {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 write!(f, "{}({:x})", stringify!($short_id), self.as_intern_id().index())
95 }
96 }
97
98 impl<'db> cairo_lang_utils::Intern<'db, $short_id<'db>> for $long_id {
99 fn intern(self, db: &'db dyn salsa::Database) -> $short_id<'db> {
100 $short_id::new(db, self)
101 }
102 }
103
104 impl<'db> $short_id<'db> {
105 pub fn from_intern_id(intern_id: salsa::Id) -> Self {
106 use salsa::plumbing::FromId;
107 Self::from_id(intern_id)
108 }
109
110 pub fn as_intern_id(self) -> salsa::Id {
111 use salsa::plumbing::AsId;
112 self.as_id()
113 }
114 }
115
116 impl<'db> cairo_lang_debug::DebugWithDb<'db> for $short_id<'db> {
118 type Db = dyn salsa::Database;
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db Self::Db) -> std::fmt::Result {
120 use core::fmt::Debug;
121
122 use cairo_lang_debug::helper::{Fallback, HelperDebug};
123
124 HelperDebug::<$long_id, dyn salsa::Database>::helper_debug(self.long(db), db).fmt(f)
125 }
126 }
127
128 impl<'db> cairo_lang_utils::HeapSize for $short_id<'db> {
131 fn heap_size(&self) -> usize {
132 0
133 }
134 }
135 };
136}
137
138pub fn with_finally<Ctx, R>(
141 ctx: &mut Ctx,
142 action: impl FnOnce(&mut Ctx) -> R,
143 finally: impl FnOnce(&mut Ctx),
144) -> R {
145 let result = action(ctx);
146 finally(ctx);
147 result
148}
149
150#[must_use = "This function is only relevant to create a possible return."]
157pub fn require(condition: bool) -> Option<()> {
158 condition.then_some(())
159}