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 extract_matches;
21#[cfg(feature = "std")]
22pub mod graph_algos;
23pub mod iterators;
24#[cfg(feature = "env_logger")]
25pub mod logging;
26pub mod ordered_hash_map;
27pub mod ordered_hash_set;
28pub mod unordered_hash_map;
29pub mod unordered_hash_set;
30
31pub trait OptionFrom<T>
33where
34 Self: Sized,
35{
36 fn option_from(other: T) -> Option<Self>;
37}
38
39pub fn write_comma_separated<Iter: IntoIterator<Item = V>, V: core::fmt::Display>(
40 f: &mut fmt::Formatter<'_>,
41 values: Iter,
42) -> fmt::Result {
43 let mut iter = values.into_iter();
44 if let Some(value) = iter.next() {
45 write!(f, "{value}")?;
46 }
47 for value in iter {
48 write!(f, ", {value}")?;
49 }
50 Ok(())
51}
52
53pub trait OptionHelper {
55 fn on_none<F: FnOnce()>(self, f: F) -> Self;
56}
57impl<T> OptionHelper for Option<T> {
58 fn on_none<F: FnOnce()>(self, f: F) -> Self {
59 if self.is_none() {
60 f();
61 }
62 self
63 }
64}
65
66pub fn borrow_as_box<T: Default, R, F: FnOnce(Box<T>) -> (R, Box<T>)>(ptr: &mut T, f: F) -> R {
82 let (res, boxed) = f(Box::new(core::mem::take(ptr)));
85 *ptr = *boxed;
86 res
87}
88
89pub trait LookupIntern<'a, DynDbGroup: ?Sized, LongId> {
91 fn lookup_intern(&self, db: &(impl Upcast<DynDbGroup> + ?Sized)) -> LongId;
92}
93pub trait Intern<'a, DynDbGroup: ?Sized, ShortId> {
94 fn intern(self, db: &(impl Upcast<DynDbGroup> + ?Sized)) -> ShortId;
95}
96
97#[macro_export]
106macro_rules! define_short_id {
107 ($short_id:ident, $long_id:path, $db:ident, $lookup:ident, $intern:ident) => {
108 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
109 pub struct $short_id(salsa::InternId);
110 impl<'a> cairo_lang_utils::LookupIntern<'a, dyn $db + 'a, $long_id> for $short_id {
111 fn lookup_intern(
112 &self,
113 db: &(impl cairo_lang_utils::Upcast<dyn $db + 'a> + ?Sized),
114 ) -> $long_id {
115 $db::$lookup(db.upcast(), *self)
116 }
117 }
118 impl<'a> cairo_lang_utils::Intern<'a, dyn $db + 'a, $short_id> for $long_id {
119 fn intern(
120 self,
121 db: &(impl cairo_lang_utils::Upcast<dyn $db + 'a> + ?Sized),
122 ) -> $short_id {
123 $db::$intern(db.upcast(), self)
124 }
125 }
126 impl salsa::InternKey for $short_id {
127 fn from_intern_id(salsa_id: salsa::InternId) -> Self {
128 Self(salsa_id)
129 }
130
131 fn as_intern_id(&self) -> salsa::InternId {
132 self.0
133 }
134 }
135 impl<T: ?Sized + cairo_lang_utils::Upcast<dyn $db + 'static>>
137 cairo_lang_debug::DebugWithDb<T> for $short_id
138 {
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &T) -> std::fmt::Result {
140 use core::fmt::Debug;
141
142 use cairo_lang_debug::helper::Fallback;
143 let db = db.upcast();
144 cairo_lang_debug::helper::HelperDebug::<$long_id, dyn $db>::helper_debug(
145 &db.$lookup(*self),
146 db,
147 )
148 .fmt(f)
149 }
150 }
151 };
152}
153
154pub trait Upcast<T: ?Sized> {
155 fn upcast(&self) -> &T;
156}
157
158impl<T: ?Sized> Upcast<T> for T {
159 fn upcast(&self) -> &T {
160 self
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}