#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use core::fmt;
pub mod bigint;
pub mod byte_array;
pub mod casts;
pub mod collection_arithmetics;
pub mod extract_matches;
#[cfg(feature = "std")]
pub mod graph_algos;
pub mod iterators;
#[cfg(feature = "env_logger")]
pub mod logging;
pub mod ordered_hash_map;
pub mod ordered_hash_set;
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: core::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 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(core::mem::take(ptr)));
*ptr = *boxed;
res
}
pub trait LookupIntern<'a, DynDbGroup: ?Sized, LongId> {
fn lookup_intern(&self, db: &(impl Upcast<DynDbGroup> + ?Sized)) -> LongId;
}
pub trait Intern<'a, DynDbGroup: ?Sized, ShortId> {
fn intern(self, db: &(impl Upcast<DynDbGroup> + ?Sized)) -> ShortId;
}
#[macro_export]
macro_rules! define_short_id {
($short_id:ident, $long_id:path, $db:ident, $lookup:ident, $intern:ident) => {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct $short_id(salsa::InternId);
impl<'a> cairo_lang_utils::LookupIntern<'a, dyn $db + 'a, $long_id> for $short_id {
fn lookup_intern(
&self,
db: &(impl cairo_lang_utils::Upcast<dyn $db + 'a> + ?Sized),
) -> $long_id {
$db::$lookup(db.upcast(), *self)
}
}
impl<'a> cairo_lang_utils::Intern<'a, dyn $db + 'a, $short_id> for $long_id {
fn intern(
self,
db: &(impl cairo_lang_utils::Upcast<dyn $db + 'a> + ?Sized),
) -> $short_id {
$db::$intern(db.upcast(), self)
}
}
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 core::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
}
}
pub trait UpcastMut<T: ?Sized> {
fn upcast_mut(&mut self) -> &mut T;
}
impl<T: ?Sized> UpcastMut<T> for T {
fn upcast_mut(&mut self) -> &mut T {
self
}
}
#[must_use = "This function is only relevant to create a possible return."]
pub fn require(condition: bool) -> Option<()> {
condition.then_some(())
}