use dupe::Dupe;
use crate::environment::GlobalsBuilder;
use crate::values::namespace::globals::register_namespace;
pub(crate) mod breakpoint;
pub(crate) mod call_stack;
pub(crate) mod extra;
mod funcs;
pub(crate) mod internal;
pub(crate) mod json;
pub(crate) mod partial;
pub use extra::PrintHandler;
use crate::stdlib::funcs::globals::register_globals;
use crate::stdlib::internal::register_internal;
use crate::values::enumeration::globals::register_enum;
use crate::values::record::globals::register_record;
use crate::values::structs::structs::register_struct;
use crate::values::types::set::set::register_set;
use crate::values::typing;
pub(crate) fn standard_environment() -> GlobalsBuilder {
GlobalsBuilder::new().with(register_globals)
}
#[derive(PartialEq, Eq, Copy, Clone, Dupe)]
pub enum LibraryExtension {
StructType,
RecordType,
EnumType,
NamespaceType,
Map,
Filter,
Partial,
Debug,
Print,
Pprint,
Pstr,
Prepr,
Breakpoint,
Json,
Typing,
Internal,
CallStack,
SetType,
}
impl LibraryExtension {
pub(crate) fn all() -> &'static [Self] {
use LibraryExtension::*;
&[
StructType,
RecordType,
EnumType,
NamespaceType,
Map,
Filter,
Partial,
Debug,
Print,
Pprint,
Pstr,
Prepr,
Breakpoint,
Json,
Typing,
Internal,
CallStack,
SetType,
]
}
pub fn add(self, builder: &mut GlobalsBuilder) {
use LibraryExtension::*;
match self {
StructType => register_struct(builder),
NamespaceType => register_namespace(builder),
RecordType => register_record(builder),
EnumType => register_enum(builder),
SetType => register_set(builder),
Map => extra::map(builder),
Filter => extra::filter(builder),
Partial => partial::partial(builder),
Debug => extra::debug(builder),
Print => extra::print(builder),
Pprint => extra::pprint(builder),
Pstr => extra::pstr(builder),
Prepr => extra::prepr(builder),
Breakpoint => breakpoint::global(builder),
Json => json::json(builder),
Typing => typing::globals::register_typing(builder),
Internal => register_internal(builder),
CallStack => call_stack::global(builder),
}
}
}
#[cfg(test)]
mod tests {
use std::convert::Infallible;
use allocative::Allocative;
use derive_more::Display;
use dupe::Dupe;
use starlark_derive::starlark_module;
use starlark_derive::starlark_value;
use starlark_derive::NoSerialize;
use crate as starlark;
use crate::any::ProvidesStaticType;
use crate::assert::Assert;
use crate::environment::GlobalsBuilder;
use crate::environment::Methods;
use crate::environment::MethodsBuilder;
use crate::environment::MethodsStatic;
use crate::starlark_simple_value;
use crate::values::none::NoneType;
use crate::values::StarlarkValue;
use crate::values::UnpackValue;
use crate::values::Value;
use crate::values::ValueLike;
#[test]
fn test_no_arg() {
#[starlark_module]
fn global(builder: &mut GlobalsBuilder) {
fn nop() -> anyhow::Result<NoneType> {
Ok(NoneType)
}
}
let env = GlobalsBuilder::new().with(global).build();
env.get("nop").unwrap();
}
#[test]
fn test_value_attributes() {
#[derive(
Copy,
Clone,
Debug,
Dupe,
PartialEq,
Display,
ProvidesStaticType,
NoSerialize,
Allocative
)]
struct Bool2(bool);
starlark_simple_value!(Bool2);
#[starlark_value(type = "bool2")]
impl<'v> StarlarkValue<'v> for Bool2 {
fn get_methods() -> Option<&'static Methods> {
static RES: MethodsStatic = MethodsStatic::new();
RES.methods(methods)
}
fn equals(&self, other: Value<'v>) -> crate::Result<bool> {
match other.downcast_ref::<Bool2>() {
None => Ok(false),
Some(v) => Ok(*v == *self),
}
}
}
impl<'v> UnpackValue<'v> for Bool2 {
type Error = Infallible;
fn unpack_value_impl(value: Value<'v>) -> Result<Option<Self>, Self::Error> {
Ok(Some(*value.downcast_ref::<Bool2>().unwrap()))
}
}
#[starlark_module]
fn globals(builder: &mut GlobalsBuilder) {
const True2: Bool2 = Bool2(true);
const False2: Bool2 = Bool2(false);
}
#[starlark_module]
fn methods(builder: &mut MethodsBuilder) {
#[starlark(attribute)]
fn invert1(this: Bool2) -> starlark::Result<Bool2> {
Ok(Bool2(!this.0))
}
fn invert2(this: Bool2) -> anyhow::Result<Bool2> {
Ok(Bool2(!this.0))
}
}
let mut a = Assert::new();
a.globals_add(globals);
a.all_true(
r#"
True2 == True2
True2 != False2
True2.invert1 == False2
False2.invert1 == True2
False2.invert2() == True2
hasattr(True2, "invert1") == True
hasattr(True2, "invert2") == True
hasattr(True2, "invert3") == False
dir(False2) == ["invert1","invert2"]
getattr(False2, "invert1") == True2
getattr(True2, "invert1") == False2
getattr(True2, "invert2")() == False2
"#,
);
}
}