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 Values.

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 Values.

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§

source

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§

source

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§

source

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.

source

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.

source

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.

source

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.

source

fn documentation(&self) -> Option<DocItem>
where Self: Sized,

Return structured documentation for self, if available.

source

fn typechecker_ty(&self) -> Option<Ty>

Type of this instance for typechecker. Note this can be more precise than generic type.

source

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([]) == '[]'
source

fn collect_repr_cycle(&self, collector: &mut String)

Invoked to print repr when a cycle is the object stack is detected.

source

fn name_for_call_stack(&self, me: Value<'v>) -> String

String used when printing call stack. repr(self) by default.

source

fn to_bool(&self) -> bool

Convert self to a boolean, as returned by the bool() function. The default implementation returns true.

source

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.

source

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.

source

fn compare(&self, other: Value<'v>) -> Result<Ordering>

Compare self with other. This method returns a result of type Ordering, or an Err if the two types differ.

source

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 as Value, meaning it has unfrozen flag, so it can be stored in a heap.
source

fn at(&self, index: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Return the result of a[index] if a is indexable.

source

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.

source

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
source

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.

source

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 and iter_stop are only called on the value returned from iterate
  • iter_next is called only before iter_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.

source

unsafe fn iter_size_hint(&self, _index: usize) -> (usize, Option<usize>)

Returns the size hint for the iterator.

source

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.

source

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.

source

fn length(&self) -> Result<i32>

Returns the length of the value, if this value is a sequence.

source

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).

source

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.

source

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.

source

fn has_attr(&self, attribute: &str, heap: &'v Heap) -> bool

Return true if an attribute of name attribute exists for the current value.

The three methods get_attr, has_attr and dir_attr must be consistent.

Default implementation of this function delegates to get_attr.

source

fn dir_attr(&self) -> Vec<String>

Return a vector of string listing all attribute of the current value.

The three methods get_attr, has_attr and dir_attr must be consistent - if you implement one, you should probably implement all three.

source

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
source

fn plus(&self, _heap: &'v Heap) -> Result<Value<'v>>

Apply the + unary operator to the current value.

§Examples
+1 == 1
source

fn minus(&self, _heap: &'v Heap) -> Result<Value<'v>>

Apply the - unary operator to the current value.

§Examples
-(1) == -1
source

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.

source

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)
source

fn sub(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Subtract other from the current value.

§Examples
1 - 2 == -1
source

fn rmul(&self, lhs: Value<'v>, heap: &'v Heap) -> Option<Result<Value<'v>>>

Called on rhs of lhs * rhs when lhs.mul returns None.

source

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)
source

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
source

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"
source

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
source

fn bit_and(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Bitwise & operator.

source

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}
source

fn bit_xor(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Bitwise ^ operator.

source

fn bit_not(&self, _heap: &'v Heap) -> Result<Value<'v>>

Bitwise ~ operator.

source

fn left_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Bitwise << operator.

source

fn right_shift(&self, other: Value<'v>, _heap: &'v Heap) -> Result<Value<'v>>

Bitwise >> operator.

source

fn bin_op_ty(_op: TypingBinOp, _rhs: &TyBasic) -> Option<Ty>

Typecheck this op rhs.

source

fn rbin_op_ty(_lhs: &TyBasic, _op: TypingBinOp) -> Option<Ty>

Typecheck lhs op this.

source

fn export_as( &self, _variable_name: &str, _eval: &mut Evaluator<'v, '_> ) -> Result<()>

Called when exporting a value under a specific name,

source

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]]
source

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).

source

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§

This trait is not object safe.

Implementors§

source§

impl<'v> StarlarkValue<'v> for StarlarkFloat

source§

const TYPE: &'static str = StarlarkFloat::TYPE

§

type Canonical = StarlarkFloat

source§

impl<'v> StarlarkValue<'v> for NativeFunction

Define the function type

source§

const TYPE: &'static str = FUNCTION_TYPE

§

type Canonical = NativeFunction

source§

impl<'v> StarlarkValue<'v> for NoneType

Define the NoneType type

source§

const TYPE: &'static str = NoneType::TYPE

§

type Canonical = NoneType

source§

impl<'v> StarlarkValue<'v> for Range

source§

const TYPE: &'static str = Range::TYPE

§

type Canonical = Range

source§

impl<'v> StarlarkValue<'v> for StarlarkStr

source§

const TYPE: &'static str = STRING_TYPE

§

type Canonical = StarlarkStr

source§

impl<'v, T: Debug + Display + Send + Sync + 'static> StarlarkValue<'v> for StarlarkAny<T>

source§

const TYPE: &'static str = "any"

§

type Canonical = StarlarkAny<T>