Trait starlark::values::StarlarkValue
source · pub trait StarlarkValue<'v>: 'v + ProvidesStaticType<'v> + Allocative + Debug + Display + Serialize + Sized {
type Canonical: StarlarkValue<'v>;
const TYPE: &'static str = _;
Show 51 methods
// Provided methods
fn get_type_value_static() -> FrozenStringValue { ... }
fn get_type_starlark_repr() -> Ty { ... }
fn matches_type(&self, ty: &str) -> bool { ... }
fn get_methods() -> Option<&'static Methods>
where Self: Sized { ... }
fn documentation(&self) -> Option<DocItem>
where Self: Sized { ... }
fn typechecker_ty(&self) -> Option<Ty> { ... }
fn collect_repr(&self, collector: &mut String) { ... }
fn collect_repr_cycle(&self, collector: &mut String) { ... }
fn name_for_call_stack(&self, me: Value<'v>) -> String { ... }
fn to_bool(&self) -> bool { ... }
fn write_hash(&self, hasher: &mut StarlarkHasher) -> Result<()> { ... }
fn equals(&self, _other: Value<'v>) -> Result<bool> { ... }
fn compare(&self, other: Value<'v>) -> Result<Ordering> { ... }
fn invoke(
&self,
_me: Value<'v>,
_args: &Arguments<'v, '_>,
_eval: &mut Evaluator<'v, '_>
) -> Result<Value<'v>> { ... }
fn at(&self, index: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn at2(
&self,
_index0: Value<'v>,
_index1: Value<'v>,
_heap: &'v Heap,
_private: Private
) -> Result<Value<'v>> { ... }
fn slice(
&self,
_start: Option<Value<'v>>,
_stop: Option<Value<'v>>,
_stride: Option<Value<'v>>,
_heap: &'v Heap
) -> Result<Value<'v>> { ... }
fn iterate_collect(&self, _heap: &'v Heap) -> Result<Vec<Value<'v>>> { ... }
unsafe fn iterate(
&self,
_me: Value<'v>,
heap: &'v Heap
) -> Result<Value<'v>> { ... }
unsafe fn iter_size_hint(&self, _index: usize) -> (usize, Option<usize>) { ... }
unsafe fn iter_next(
&self,
_index: usize,
_heap: &'v Heap
) -> Option<Value<'v>> { ... }
unsafe fn iter_stop(&self) { ... }
fn length(&self) -> Result<i32> { ... }
fn attr_ty(_name: &str) -> Option<Ty> { ... }
fn get_attr(&self, _attribute: &str, _heap: &'v Heap) -> Option<Value<'v>> { ... }
fn get_attr_hashed(
&self,
attribute: Hashed<&str>,
heap: &'v Heap
) -> Option<Value<'v>> { ... }
fn has_attr(&self, attribute: &str, heap: &'v Heap) -> bool { ... }
fn dir_attr(&self) -> Vec<String> { ... }
fn is_in(&self, other: Value<'v>) -> Result<bool> { ... }
fn plus(&self, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn minus(&self, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn radd(
&self,
_lhs: Value<'v>,
_heap: &'v Heap
) -> Option<Result<Value<'v>>> { ... }
fn add(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>> { ... }
fn sub(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn rmul(&self, lhs: Value<'v>, heap: &'v Heap) -> Option<Result<Value<'v>>> { ... }
fn mul(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>> { ... }
fn div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn percent(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn floor_div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn bit_and(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn bit_or(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn bit_xor(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn bit_not(&self, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn left_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>> { ... }
fn right_shift(
&self,
other: Value<'v>,
_heap: &'v Heap
) -> Result<Value<'v>> { ... }
fn bin_op_ty(_op: TypingBinOp, _rhs: &TyBasic) -> Option<Ty> { ... }
fn rbin_op_ty(_lhs: &TyBasic, _op: TypingBinOp) -> Option<Ty> { ... }
fn export_as(
&self,
_variable_name: &str,
_eval: &mut Evaluator<'v, '_>
) -> Result<()> { ... }
fn set_at(&self, _index: Value<'v>, _new_value: Value<'v>) -> Result<()> { ... }
fn set_attr(&self, attribute: &str, _new_value: Value<'v>) -> Result<()> { ... }
fn provide(&'v self, demand: &mut Demand<'_, 'v>) { ... }
}
Expand description
How to put a Rust values into Value
s.
Every Rust value stored in a Value
must implement this trait.
You must also implement ComplexValue
if:
- A type is mutable, if you ever need to get a
&mut self
reference to it. - A type contains nested Starlark
Value
s.
There are only two required members of StarlarkValue
, namely
TYPE
and get_type_value_static
.
Both these should be implemented with the starlark_value
proc macro:
use allocative::Allocative;
use derive_more::Display;
use starlark::values::NoSerialize;
use starlark::values::ProvidesStaticType;
use starlark::values::StarlarkValue;
use starlark_derive::starlark_value;
#[derive(Debug, Display, ProvidesStaticType, NoSerialize, Allocative)]
#[display(fmt = "Foo")]
struct Foo;
#[starlark_value(type = "foo")]
impl<'v> StarlarkValue<'v> for Foo {}
Every additional field enables further features in Starlark. In most cases the default
implementation returns an “unimplemented” Err
.
§Note To Implementors
Any additional methods that are added to this trait also need to be added to the
StarlarkValue
implementation in crate::values::layout::avalue::Wrapper
. Otherwise,
any implementations other than the default implementation will not be run.
Required Associated Types§
sourcetype Canonical: StarlarkValue<'v>
type Canonical: StarlarkValue<'v>
Two implementations of StarlarkValue
are considered to have the same type,
if Canonical
field points to the same type.
This field is generated by #[starlark_value]
proc macro by default
when proc macro can infer the type, otherwise this implementation cannot serve as a type.
Provided Associated Constants§
sourceconst TYPE: &'static str = _
const TYPE: &'static str = _
Return a string describing the type of self, as returned by the type() function.
This can be only implemented by the #[starlark_value]
proc macro.
Provided Methods§
sourcefn get_type_value_static() -> FrozenStringValue
fn get_type_value_static() -> FrozenStringValue
Like TYPE
, but returns a reusable FrozenStringValue
pointer to it. This function deliberately doesn’t take a heap,
as it would not be performant to allocate a new value each time.
This can be only implemented by the #[starlark_value]
proc macro.
sourcefn get_type_starlark_repr() -> Ty
fn get_type_starlark_repr() -> Ty
Return a string that is the representation of a type that a user would use in
type annotations. This often will be the same as Self::TYPE
, but in
some instances it might be slightly different than what is returned by TYPE
.
This can be only implemented by the #[starlark_value]
proc macro.
sourcefn matches_type(&self, ty: &str) -> bool
fn matches_type(&self, ty: &str) -> bool
Is this value a match for a named type. Usually returns true
for
values matching get_type
, but might also work for subtypes it implements.
sourcefn get_methods() -> Option<&'static Methods>where
Self: Sized,
fn get_methods() -> Option<&'static Methods>where
Self: Sized,
Get the members associated with this type, accessible via this_type.x
.
These members will have dir
/getattr
/hasattr
properly implemented,
so it is the preferred way to go if possible. See
MethodsStatic
for an example of how
to define this method.
sourcefn documentation(&self) -> Option<DocItem>where
Self: Sized,
fn documentation(&self) -> Option<DocItem>where
Self: Sized,
Return structured documentation for self, if available.
sourcefn typechecker_ty(&self) -> Option<Ty>
fn typechecker_ty(&self) -> Option<Ty>
Type of this instance for typechecker. Note this can be more precise than generic type.
sourcefn collect_repr(&self, collector: &mut String)
fn collect_repr(&self, collector: &mut String)
Return a string representation of self, as returned by the repr()
function.
Defaults to the Display
instance - which should be fine for nearly all types.
In many cases the repr()
representation will also be a Starlark expression
for creating the value.
repr("test") == '"test"'
repr([1,2,3]) == '[1, 2, 3]'
repr([1,[2,3]]) == '[1, [2, 3]]'
repr([1]) == '[1]'
repr([]) == '[]'
sourcefn collect_repr_cycle(&self, collector: &mut String)
fn collect_repr_cycle(&self, collector: &mut String)
Invoked to print repr
when a cycle is the object stack is detected.
sourcefn name_for_call_stack(&self, me: Value<'v>) -> String
fn name_for_call_stack(&self, me: Value<'v>) -> String
String used when printing call stack. repr(self)
by default.
sourcefn to_bool(&self) -> bool
fn to_bool(&self) -> bool
Convert self to a boolean, as returned by the bool() function.
The default implementation returns true
.
sourcefn write_hash(&self, hasher: &mut StarlarkHasher) -> Result<()>
fn write_hash(&self, hasher: &mut StarlarkHasher) -> Result<()>
Return a hash data for self to be used when self is placed as a key in a Dict
.
Return an Err
if there is no hash for this value (e.g. list).
Must be stable between frozen and non-frozen values.
sourcefn equals(&self, _other: Value<'v>) -> Result<bool>
fn equals(&self, _other: Value<'v>) -> Result<bool>
Compare self
with other
for equality.
Should only return an error on excessive recursion.
This function can only be called when it is known that self pointer
is not equal to the other pointer. Thus, an implementation may assume
that the pointers are not equal. Implementation of equals
for some
builtin types and default implementation rely on this assumption.
Equality must be symmetric (a == b
implies b == a
).
When evaluating a == b
(or when using equality in dicts and such),
it is not specified whether a.equals(b)
or b.equals(a)
is called.
sourcefn invoke(
&self,
_me: Value<'v>,
_args: &Arguments<'v, '_>,
_eval: &mut Evaluator<'v, '_>
) -> Result<Value<'v>>
fn invoke( &self, _me: Value<'v>, _args: &Arguments<'v, '_>, _eval: &mut Evaluator<'v, '_> ) -> Result<Value<'v>>
Directly invoke a function.
The number of named
and names
arguments are guaranteed to be equal.
§Parameters
me
- self, but asValue
, meaning it has unfrozen flag, so it can be stored in a heap.
sourcefn at(&self, index: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn at(&self, index: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Return the result of a[index]
if a
is indexable.
sourcefn at2(
&self,
_index0: Value<'v>,
_index1: Value<'v>,
_heap: &'v Heap,
_private: Private
) -> Result<Value<'v>>
fn at2( &self, _index0: Value<'v>, _index1: Value<'v>, _heap: &'v Heap, _private: Private ) -> Result<Value<'v>>
Return the result of a[index0, index1]
if a
is indexable by two parameters.
sourcefn slice(
&self,
_start: Option<Value<'v>>,
_stop: Option<Value<'v>>,
_stride: Option<Value<'v>>,
_heap: &'v Heap
) -> Result<Value<'v>>
fn slice( &self, _start: Option<Value<'v>>, _stop: Option<Value<'v>>, _stride: Option<Value<'v>>, _heap: &'v Heap ) -> Result<Value<'v>>
Extract a slice of the underlying object if the object is indexable. The
result will be object between start
and stop
(both of them are
added length() if negative and then clamped between 0 and length()).
stride
indicates the direction.
§Parameters
- start: the start of the slice.
- stop: the end of the slice.
- stride: the direction of slice,
§Examples
'abc'[1:] == 'bc' # Remove the first element
'abc'[:-1] == 'ab' # Remove the last element
'abc'[1:-1] == 'b' # Remove the first and the last element
'abc'[-1:] == 'c' # Take the last letter
'abc'[:1] == 'a' # Take the first letter
'banana'[1::2] == 'aaa' # Select one element out of 2, skipping the first
'banana'[4::-2] == 'nnb' # Select one element out of 2 in reverse order, starting at index 4
sourcefn iterate_collect(&self, _heap: &'v Heap) -> Result<Vec<Value<'v>>>
fn iterate_collect(&self, _heap: &'v Heap) -> Result<Vec<Value<'v>>>
Implement iteration over the value of this container by providing
the values in a Vec
.
sourceunsafe fn iterate(&self, _me: Value<'v>, heap: &'v Heap) -> Result<Value<'v>>
unsafe fn iterate(&self, _me: Value<'v>, heap: &'v Heap) -> Result<Value<'v>>
Returns an iterator over the value of this container if this value holds an iterable container.
This function is hard to implement correctly. For example, returning a list from this function is memory violation, because the list object acting as an iterator is assumed to have the iteration lock acquired.
Consider implementing iterate_collect
instead
when possible.
This function calls iterate_collect
by default.
Returned iterator value must implement
iter_next
and iter_stop
.
Default implementations of these functions panic.
Starlark-rust guarantees that
iter_next
anditer_stop
are only called on the value returned fromiterate
iter_next
is called only beforeiter_stop
iter_stop
is called exactly once
So implementations of iterators may acquire mutation lock in iterate
,
assume that it is held in iter_next
, and release it in iter_stop
.
Obviously, there are no such guarantees if these functions are called directly.
sourceunsafe fn iter_size_hint(&self, _index: usize) -> (usize, Option<usize>)
unsafe fn iter_size_hint(&self, _index: usize) -> (usize, Option<usize>)
Returns the size hint for the iterator.
sourceunsafe fn iter_next(&self, _index: usize, _heap: &'v Heap) -> Option<Value<'v>>
unsafe fn iter_next(&self, _index: usize, _heap: &'v Heap) -> Option<Value<'v>>
Yield the next value from the iterator.
This function is called on the iterator value returned by iterate
.
This function accepts an index, which starts at 0 and is incremented by 1
for each call to iter_next
. The index can be used to implement
cheap iteration over simple containers like lists:
list iterate
just returns the list itself,
and the passed index is used to access the list elements.
Default implementation panics.
This function is only called before iter_stop
.
sourceunsafe fn iter_stop(&self)
unsafe fn iter_stop(&self)
Indicate that the iteration is finished.
This function is typically used to release mutation lock. The function must be implemented for iterators even if it does nothing.
This function is called exactly once for the iterator.
sourcefn attr_ty(_name: &str) -> Option<Ty>
fn attr_ty(_name: &str) -> Option<Ty>
Attribute type, for the typechecker.
If get_attr
is implemented,
#[starlark_value]
proc macro will generate this to return Some(Any)
.
sourcefn get_attr(&self, _attribute: &str, _heap: &'v Heap) -> Option<Value<'v>>
fn get_attr(&self, _attribute: &str, _heap: &'v Heap) -> Option<Value<'v>>
Get an attribute for the current value as would be returned by dotted
expression (i.e. a.attribute
).
The three methods get_attr
,
has_attr
and dir_attr
must be consistent - if you implement one, you should probably implement all three.
This operations must have no side effects, because it can be called speculatively.
sourcefn get_attr_hashed(
&self,
attribute: Hashed<&str>,
heap: &'v Heap
) -> Option<Value<'v>>
fn get_attr_hashed( &self, attribute: Hashed<&str>, heap: &'v Heap ) -> Option<Value<'v>>
A version of get_attr
which takes BorrowHashed<str>
instead of &str
,
thus implementation may reuse the hash of the string if this is called
repeatedly with the same string.
This function is optional, but if it is implemented, it must be consistent with
get_attr
.
sourcefn is_in(&self, other: Value<'v>) -> Result<bool>
fn is_in(&self, other: Value<'v>) -> Result<bool>
Tell whether other
is in the current value, if it is a container.
§Examples
('a' in 'abc') == True
('b' in 'abc') == True
('z' in 'abc') == False
sourcefn radd(&self, _lhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
fn radd(&self, _lhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
Add with the arguments the other way around. Should return None
to fall through to normal add.
sourcefn add(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
fn add(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
Add other
to the current value. Pass both self and
the Value form of self as original.
§Examples
1 + 2 == 3
[1, 2, 3] + [2, 3] == [1, 2, 3, 2, 3]
'abc' + 'def' == 'abcdef'
(1, 2, 3) + (2, 3) == (1, 2, 3, 2, 3)
sourcefn rmul(&self, lhs: Value<'v>, heap: &'v Heap) -> Option<Result<Value<'v>>>
fn rmul(&self, lhs: Value<'v>, heap: &'v Heap) -> Option<Result<Value<'v>>>
Called on rhs
of lhs * rhs
when lhs.mul
returns None
.
sourcefn mul(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
fn mul(&self, _rhs: Value<'v>, _heap: &'v Heap) -> Option<Result<Value<'v>>>
Multiply the current value with other
.
When this function returns None
, starlark-rust calls rhs.rmul(lhs)
.
§Examples
2 * 3 == 6
[1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]
'abc' * 3 == 'abcabcabc'
(1, 2, 3) * 3 == (1, 2, 3, 1, 2, 3, 1, 2, 3)
sourcefn div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Divide the current value by other
. Always results in a float value.
§Examples
4 / 2.0 == 2.0
7 / 2 == 3.5
sourcefn percent(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn percent(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Apply the percent operator between the current value and other
. Usually used on
strings, as per
the Starlark spec.
§Examples
5 % 3 == 2
-5 % -3 == -2
5 % -3 == -1
-5 % 3 == 1
5.5 % 3.0 == 2.5
-5.5 % 3.0 == 0.5
5.5 % -3.0 == -0.5
-5.5 % -3.0 == -2.5
"a %s c" % 3 == "a 3 c"
"Hello %s, your score is %d" % ("Bob", 75) == "Hello Bob, your score is 75"
"%d %o %x" % (65, 65, 65) == "65 101 41"
"%d" % 12345678901234567890 == "12345678901234567890"
"Hello %s, welcome" % "Bob" == "Hello Bob, welcome"
"%s" % (1,) == "1"
"%s" % ((1,),) == "(1,)"
"%s" % [1] == "[1]"
"test" % () == "test"
sourcefn floor_div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn floor_div(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Floor division between the current value and other
.
§Examples
7 // 2 == 3
-7 // -2 == 3
7 // -2 == -4
-7 // 2 == -4
7.0 // 2.0 == 3.0
-7.0 // -2.0 == 3.0
7.0 // -2.0 == -4.0
-7.0 // 2.0 == -4.0
3.0 // 2.0 == 1.0
sourcefn bit_or(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn bit_or(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Bitwise |
operator.
§Examples
0xb00f | 0x0ee0 == 0xbeef
4 | 7 == 7
{1: 2} | {3: 4} == {1: 2, 3: 4}
{1: 2} | {1: 3} == {1: 3}
sourcefn left_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn left_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Bitwise <<
operator.
sourcefn right_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
fn right_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>
Bitwise >>
operator.
sourcefn rbin_op_ty(_lhs: &TyBasic, _op: TypingBinOp) -> Option<Ty>
fn rbin_op_ty(_lhs: &TyBasic, _op: TypingBinOp) -> Option<Ty>
Typecheck lhs op this
.
sourcefn export_as(
&self,
_variable_name: &str,
_eval: &mut Evaluator<'v, '_>
) -> Result<()>
fn export_as( &self, _variable_name: &str, _eval: &mut Evaluator<'v, '_> ) -> Result<()>
Called when exporting a value under a specific name,
sourcefn set_at(&self, _index: Value<'v>, _new_value: Value<'v>) -> Result<()>
fn set_at(&self, _index: Value<'v>, _new_value: Value<'v>) -> Result<()>
Set the value at index
with the new value.
v = [1, 2, 3]
v[1] = 1
v[2] = [2,3]
v == [1, 1, [2, 3]]
sourcefn set_attr(&self, attribute: &str, _new_value: Value<'v>) -> Result<()>
fn set_attr(&self, attribute: &str, _new_value: Value<'v>) -> Result<()>
Set the attribute named attribute
of the current value to
value
(e.g. a.attribute = value
).
sourcefn provide(&'v self, demand: &mut Demand<'_, 'v>)
fn provide(&'v self, demand: &mut Demand<'_, 'v>)
Dynamically provide values based on type.
Value can be fetched using Value::request_value
.
The API is based on std::any::Provider.
Object Safety§
Implementors§
source§impl<'v> StarlarkValue<'v> for StarlarkFloat
impl<'v> StarlarkValue<'v> for StarlarkFloat
source§impl<'v> StarlarkValue<'v> for NativeFunction
impl<'v> StarlarkValue<'v> for NativeFunction
Define the function type
source§impl<'v> StarlarkValue<'v> for NoneType
impl<'v> StarlarkValue<'v> for NoneType
Define the NoneType type