1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::fmt;
pub mod casts;
pub mod collection_arithmetics;
pub mod extract_matches;
pub mod logging;
pub mod ordered_hash_map;
pub mod ordered_hash_set;
pub mod strongly_connected_components;
pub mod unordered_hash_map;
pub mod unordered_hash_set;
pub trait OptionFrom<T>
where
Self: Sized,
{
fn option_from(other: T) -> Option<Self>;
}
pub fn write_comma_separated<Iter: IntoIterator<Item = V>, V: std::fmt::Display>(
f: &mut fmt::Formatter<'_>,
values: Iter,
) -> fmt::Result {
let mut iter = values.into_iter();
if let Some(value) = iter.next() {
write!(f, "{value}")?;
}
for value in iter {
write!(f, ", {value}")?;
}
Ok(())
}
pub trait OptionHelper {
fn on_none<F: FnOnce()>(self, f: F) -> Self;
}
impl<T> OptionHelper for Option<T> {
fn on_none<F: FnOnce()>(self, f: F) -> Self {
if self.is_none() {
f();
}
self
}
}
pub trait ResultHelper<E> {
fn on_err<F: FnOnce(&E)>(self, f: F) -> Self;
}
impl<T, E> ResultHelper<E> for Result<T, E> {
fn on_err<F: FnOnce(&E)>(self, f: F) -> Self {
match &self {
Ok(_) => self,
Err(e) => {
f(e);
self
}
}
}
}
pub fn borrow_as_box<T: Default, R, F: FnOnce(Box<T>) -> (R, Box<T>)>(ptr: &mut T, f: F) -> R {
let (res, boxed) = f(Box::new(std::mem::take(ptr)));
*ptr = *boxed;
res
}
#[macro_export]
macro_rules! define_short_id {
($short_id:ident, $long_id:ident, $db:ident, $lookup:ident) => {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct $short_id(salsa::InternId);
impl salsa::InternKey for $short_id {
fn from_intern_id(salsa_id: salsa::InternId) -> Self {
Self(salsa_id)
}
fn as_intern_id(&self) -> salsa::InternId {
self.0
}
}
impl<T: ?Sized + cairo_lang_utils::Upcast<dyn $db + 'static>>
cairo_lang_debug::DebugWithDb<T> for $short_id
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>, db: &T) -> std::fmt::Result {
use std::fmt::Debug;
use cairo_lang_debug::helper::Fallback;
let db = db.upcast();
cairo_lang_debug::helper::HelperDebug::<$long_id, dyn $db>::helper_debug(
&db.$lookup(*self),
db,
)
.fmt(f)
}
}
};
}
pub trait Upcast<T: ?Sized> {
fn upcast(&self) -> &T;
}
impl<T: ?Sized> Upcast<T> for T {
fn upcast(&self) -> &T {
self
}
}