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;
24pub mod iterators;
25#[cfg(feature = "tracing")]
26pub mod logging;
27pub mod ordered_hash_map;
28pub mod ordered_hash_set;
29#[cfg(feature = "std")]
30pub mod small_ordered_map;
31pub mod unordered_hash_map;
32pub mod unordered_hash_set;
33
34pub trait OptionFrom<T>
36where
37 Self: Sized,
38{
39 fn option_from(other: T) -> Option<Self>;
40}
41
42pub fn write_comma_separated<Iter: IntoIterator<Item = V>, V: core::fmt::Display>(
43 f: &mut fmt::Formatter<'_>,
44 values: Iter,
45) -> fmt::Result {
46 let mut iter = values.into_iter();
47 if let Some(value) = iter.next() {
48 write!(f, "{value}")?;
49 }
50 for value in iter {
51 write!(f, ", {value}")?;
52 }
53 Ok(())
54}
55
56pub trait OptionHelper {
58 fn on_none<F: FnOnce()>(self, f: F) -> Self;
59}
60impl<T> OptionHelper for Option<T> {
61 fn on_none<F: FnOnce()>(self, f: F) -> Self {
62 if self.is_none() {
63 f();
64 }
65 self
66 }
67}
68
69pub fn borrow_as_box<T: Default, R, F: FnOnce(Box<T>) -> (R, Box<T>)>(ptr: &mut T, f: F) -> R {
85 let (res, boxed) = f(Box::new(core::mem::take(ptr)));
88 *ptr = *boxed;
89 res
90}
91
92#[cfg(feature = "std")]
93pub trait Intern<'db, Target> {
94 fn intern(self, db: &'db dyn salsa::Database) -> Target;
95}
96
97#[macro_export]
107macro_rules! define_short_id {
108 ($short_id:ident, $long_id:path) => {
109 #[salsa::interned(revisions = usize::MAX)]
111 pub struct $short_id<'db> {
112 #[returns(ref)]
113 pub long: $long_id,
114 }
115
116 impl<'db> std::fmt::Debug for $short_id<'db> {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 write!(f, "{}({:x})", stringify!($short_id), self.as_intern_id().index())
119 }
120 }
121
122 impl<'db> cairo_lang_utils::Intern<'db, $short_id<'db>> for $long_id {
123 fn intern(self, db: &'db dyn salsa::Database) -> $short_id<'db> {
124 $short_id::new(db, self)
125 }
126 }
127
128 impl<'db> $short_id<'db> {
129 pub fn from_intern_id(intern_id: salsa::Id) -> Self {
130 use salsa::plumbing::FromId;
131 Self::from_id(intern_id)
132 }
133
134 pub fn as_intern_id(self) -> salsa::Id {
135 use salsa::plumbing::AsId;
136 self.as_id()
137 }
138 }
139
140 impl<'db> cairo_lang_debug::DebugWithDb<'db> for $short_id<'db> {
142 type Db = dyn salsa::Database;
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &'db Self::Db) -> std::fmt::Result {
144 use core::fmt::Debug;
145
146 use cairo_lang_debug::helper::{Fallback, HelperDebug};
147
148 HelperDebug::<$long_id, dyn salsa::Database>::helper_debug(self.long(db), db).fmt(f)
149 }
150 }
151 };
152}
153
154#[must_use = "This function is only relevant to create a possible return."]
161pub fn require(condition: bool) -> Option<()> {
162 condition.then_some(())
163}