1#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(not(feature = "std"))]
6extern crate alloc;
7
8#[cfg(not(feature = "std"))]
9use alloc::boxed::Box;
10use core::fmt;
11
12pub use ::smol_str;
15
16pub mod bigint;
17pub mod byte_array;
18pub mod casts;
19pub mod collection_arithmetics;
20pub mod deque;
21pub mod extract_matches;
22#[cfg(feature = "std")]
23pub mod graph_algos;
24#[cfg(feature = "std")]
25pub mod heap_size;
26pub mod iterators;
27#[cfg(feature = "tracing")]
28pub mod logging;
29pub mod ordered_hash_map;
30pub mod ordered_hash_set;
31#[cfg(feature = "std")]
32pub mod small_ordered_map;
33pub mod unordered_hash_map;
34pub mod unordered_hash_set;
35
36#[cfg(feature = "std")]
37pub use heap_size::HeapSize;
38
39pub trait OptionFrom<T>: Sized {
41 fn option_from(other: T) -> Option<Self>;
42}
43
44pub fn write_comma_separated<Iter: IntoIterator<Item = V>, V: core::fmt::Display>(
45 f: &mut fmt::Formatter<'_>,
46 values: Iter,
47) -> fmt::Result {
48 let mut iter = values.into_iter();
49 if let Some(value) = iter.next() {
50 write!(f, "{value}")?;
51 }
52 for value in iter {
53 write!(f, ", {value}")?;
54 }
55 Ok(())
56}
57
58pub trait OptionHelper {
60 fn on_none<F: FnOnce()>(self, f: F) -> Self;
61}
62impl<T> OptionHelper for Option<T> {
63 fn on_none<F: FnOnce()>(self, f: F) -> Self {
64 if self.is_none() {
65 f();
66 }
67 self
68 }
69}
70
71pub fn borrow_as_box<T: Default, R, F: FnOnce(Box<T>) -> (R, Box<T>)>(ptr: &mut T, f: F) -> R {
87 let (res, boxed) = f(Box::new(core::mem::take(ptr)));
90 *ptr = *boxed;
91 res
92}
93
94#[cfg(feature = "std")]
95pub trait Intern<'db, Target> {
96 fn intern(self, db: &'db dyn salsa::Database) -> Target;
97}
98
99#[macro_export]
109macro_rules! define_short_id {
110 ($short_id:ident, $long_id:path) => {
111 #[cairo_lang_proc_macros::interned(revisions = usize::MAX)]
113 pub struct $short_id<'db> {
114 #[returns(ref)]
115 pub long: $long_id,
116 }
117
118 impl<'db> std::fmt::Debug for $short_id<'db> {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 write!(f, "{}({:x})", stringify!($short_id), self.as_intern_id().index())
121 }
122 }
123
124 impl<'db> cairo_lang_utils::Intern<'db, $short_id<'db>> for $long_id {
125 fn intern(self, db: &'db dyn salsa::Database) -> $short_id<'db> {
126 $short_id::new(db, self)
127 }
128 }
129
130 impl<'db> $short_id<'db> {
131 pub fn from_intern_id(intern_id: salsa::Id) -> Self {
132 use salsa::plumbing::FromId;
133 Self::from_id(intern_id)
134 }
135
136 pub fn as_intern_id(self) -> salsa::Id {
137 use salsa::plumbing::AsId;
138 self.as_id()
139 }
140 }
141
142 impl<'db> cairo_lang_debug::DebugWithDb<'db> for $short_id<'db> {
144 type Db = dyn salsa::Database;
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db Self::Db) -> std::fmt::Result {
146 use core::fmt::Debug;
147
148 use cairo_lang_debug::helper::{Fallback, HelperDebug};
149
150 HelperDebug::<$long_id, dyn salsa::Database>::helper_debug(self.long(db), db).fmt(f)
151 }
152 }
153
154 impl<'db> cairo_lang_utils::HeapSize for $short_id<'db> {
157 fn heap_size(&self) -> usize {
158 0
159 }
160 }
161 };
162}
163
164#[must_use = "This function is only relevant to create a possible return."]
171pub fn require(condition: bool) -> Option<()> {
172 condition.then_some(())
173}