use dupe::Dupe;
use once_cell::sync::Lazy;
use crate::environment::Globals;
use crate::values::namespace::FrozenNamespace;
use crate::values::FrozenValue;
#[derive(Copy, Clone, Dupe, Debug)]
pub(crate) struct BuiltinFn(pub(crate) FrozenValue);
impl PartialEq<FrozenValue> for BuiltinFn {
fn eq(&self, other: &FrozenValue) -> bool {
self.0.to_value().ptr_eq(other.to_value())
}
}
impl PartialEq<BuiltinFn> for FrozenValue {
fn eq(&self, other: &BuiltinFn) -> bool {
other == self
}
}
pub(crate) struct Constants {
pub(crate) fn_len: BuiltinFn,
pub(crate) fn_type: BuiltinFn,
pub(crate) fn_list: BuiltinFn,
pub(crate) fn_dict: BuiltinFn,
pub(crate) fn_tuple: BuiltinFn,
pub(crate) fn_isinstance: BuiltinFn,
pub(crate) fn_set: BuiltinFn,
pub(crate) typing_callable: BuiltinFn,
}
impl Constants {
pub fn get() -> &'static Constants {
static RES: Lazy<Constants> = Lazy::new(|| {
let g = Globals::extended_internal();
Constants {
fn_len: BuiltinFn(g.get_frozen("len").unwrap()),
fn_type: BuiltinFn(g.get_frozen("type").unwrap()),
fn_list: BuiltinFn(g.get_frozen("list").unwrap()),
fn_dict: BuiltinFn(g.get_frozen("dict").unwrap()),
fn_tuple: BuiltinFn(g.get_frozen("tuple").unwrap()),
fn_isinstance: BuiltinFn(g.get_frozen("isinstance").unwrap()),
fn_set: BuiltinFn(g.get_frozen("set").unwrap()),
typing_callable: {
let typing = g
.get_frozen("typing")
.unwrap()
.downcast_frozen_ref::<FrozenNamespace>()
.unwrap();
BuiltinFn(typing.as_ref().get("Callable").unwrap())
},
}
});
Lazy::force(&RES)
}
}
#[cfg(test)]
mod tests {
use crate::environment::Globals;
use crate::eval::compiler::constants::Constants;
#[test]
fn test_constants() {
assert_eq!(
Globals::standard().get_frozen("len").unwrap(),
Constants::get().fn_len
);
assert_eq!(
Globals::extended_internal().get_frozen("len").unwrap(),
Constants::get().fn_len
);
}
}