[][src]Struct jlrs::value::Value

#[repr(transparent)]pub struct Value<'frame, 'data>(_, _, _);

When working with the Julia C API most data is returned as a raw pointer to a jl_value_t. This pointer is similar to a void pointer in the sense that this pointer can point to data of any type. It's up to the user to determine the correct type and cast the pointer. In order to make this possible, data pointed to by a jl_value_t-pointer is guaranteed to be preceded in memory by a fixed-size header that contains its type and layout-information.

A Value is a wrapper around the raw pointer to a jl_value_t that adds two lifetimes, 'frame and 'data. The first is inherited from the frame used to create the Value; frames ensure a Value is protected from garbage collection as long as the frame used to protect it has not been dropped. As a result, a Value can only be used when it can be guaranteed that the garbage collector won't drop it. The second indicates the lifetime of its contents; it's usually 'static, but if you create a Value that borrows array data from Rust it's the lifetime of the borrow. If you call a Julia function the returned Value will inherit the 'data-lifetime of the Values used as arguments. This ensures that a Value that (possibly) borrows data from Rust can't be used after that borrow ends. If this restriction is too strict you can forget the second lifetime by calling Value::assume_owned.

Creating new values

New Values can be created from Rust in several ways. Types that implement IntoJulia can be converted to a Value by calling Value::new. This trait is implemented by primitive types like bool, char, i16, and usize; string types like String, &str, and Cow; tuples; and you can derive it for your own types by deriving IntoJulia. You should use JlrsReflect.jl rather than doing this manually.

Value also has several methods to create an n-dimensional array if the element type implements IntoJulia, this includes primitive types, strings. It is also implemented for bits types with no type parameters when these bindings are generated with JlrsReflect.jl. A new array whose data is completely managed by Julia can be created by calling Value::new_array. You can also transfer the ownership of some Vec to Julia and treat it as an n-dimensional array with Value::move_array. Finally, you can borrow anything that can be borrowed as a mutable slice with Value::borrow_array.

Functions and other global values defined in a module can be accessed through that module. Please see the documentation for Module for more information.

Casting values

A Value's type information can be accessed by calling Value::datatype, this is usually not necessary to determine what kind of data it contains; you can use Value::is to query properties of the value's type. You can use Value::cast to convert the value to the appropriate type. If a type implements both JuliaTypecheck and Cast, which are used by Value::is and Value::cast respectively, the former returning true when called with that type as generic parameter indicates that the latter will succeed. For example, value.is::<u8>() returning true means value.cast::<u8>() will succeed. You can derive these traits for custom structs by deriving JuliaStruct.

The methods that create a new Value come in two varieties: <method> and <method>_output. The first will use a slot in the current frame to protect the value from garbage collection, while the latter uses a slot in another active frame.

Implementations

impl<'frame, 'data> Value<'frame, 'data>[src]

pub fn nothing<F>(_frame: &mut F) -> Value<'frame, 'static> where
    F: Frame<'frame>, 
[src]

Returns nothing as a Value. Because nothing is a singleton this takes no slot on the GC stack.

pub fn new<V, F>(frame: &mut F, value: V) -> JlrsResult<Value<'frame, 'static>> where
    V: IntoJulia,
    F: Frame<'frame>, 
[src]

Create a new Julia value, any type that implements IntoJulia can be converted using this function. The value will be protected from garbage collection inside the frame used to create it. One free slot on the GC stack is required for this function to succeed, returns an error if no slot is available.

pub fn new_output<'output, V, F>(
    frame: &mut F,
    output: Output<'output>,
    value: V
) -> Value<'output, 'static> where
    V: IntoJulia,
    F: Frame<'frame>, 
[src]

Create a new Julia value using the output to protect it from garbage collection, any type that implements IntoJulia can be converted using this function. The value will be protected from garbage collection until the frame the output belongs to goes out of scope.

pub fn is_nothing(self) -> bool[src]

Returns true if the value is nothing.

pub fn is<T: JuliaTypecheck>(self) -> bool[src]

Performs the given type check. For types that represent Julia data, this check comes down to checking if the data has that type. This works for primitive types, for example:

julia.frame(1, |_global, frame| {
    let i = Value::new(frame, 2u64)?;
    assert!(i.is::<u64>());
    Ok(())
}).unwrap();

"Special" types in Julia that are defined in C, like Array, Module and DataType, are also supported:

julia.frame(1, |_global, frame| {
    let arr = Value::new_array::<f64, _, _>(frame, (3, 3))?;
    assert!(arr.is::<Array>());
    Ok(())
}).unwrap();

If you derive JuliaStruct for some type, that type will be supported by this method. A full list of supported checks can be found here.

pub fn datatype(self) -> Option<DataType<'frame>>[src]

Returns the DataType of this value, or None if the value constains a null pointer.

pub fn cast<T: Cast<'frame, 'data>>(
    self
) -> JlrsResult<<T as Cast<'frame, 'data>>::Output>
[src]

Cast the contents of this value into a compatible Rust type. Any type which implements Cast can be used as a target, by default this includes primitive types like u8, f32 and bool, and builtin types like Array, JuliaString and Symbol. You can implement this trait for custom types by deriving JuliaStruct.

pub unsafe fn cast_unchecked<T: Cast<'frame, 'data>>(
    self
) -> <T as Cast<'frame, 'data>>::Output
[src]

Cast the contents of this value into a compatible Rust type without checking if the layout is valid.

Safety:

You must guarantee self.is::<T>() would have returned true.

pub fn type_name(self) -> &'frame str[src]

Returns the type name of this value.

pub fn is_array_of<T: ValidLayout>(self) -> bool[src]

Returns true if the value is an array with elements of type T.

pub fn field_names(self) -> &'frame [Symbol<'frame>][src]

Returns the field names of this value as a slice of Symbols. These symbols can be used to access their fields with Value::get_field.

pub fn n_fields(self) -> usize[src]

Returns the number of fields the underlying Julia value has. These fields can be accessed with Value::get_field_n.

pub fn get_nth_field<'fr, F>(
    self,
    frame: &mut F,
    idx: usize
) -> JlrsResult<Value<'fr, 'data>> where
    F: Frame<'fr>, 
[src]

Returns the field at index idx if it exists. If it does not exist JlrsError::OutOfBounds is returned. This function assumes the field must be protected from garbage collection, so calling this function will take a single slot on the GC stack. If there is no slot available JlrsError::AllocError is returned.

pub fn get_nth_field_output<'output, 'fr, F>(
    self,
    frame: &mut F,
    output: Output<'output>,
    idx: usize
) -> JlrsResult<Value<'output, 'data>> where
    F: Frame<'fr>, 
[src]

Returns the field at index idx if it exists. If it does not exist JlrsError::OutOfBounds is returned. This function assumes the field must be protected from garbage collection and uses the provided output to do so.

pub unsafe fn get_nth_field_noalloc(
    self,
    idx: usize
) -> JlrsResult<Value<'frame, 'data>>
[src]

Returns the field at index idx if it exists and no allocation is required to return it. Allocation is not required if the field is a pointer to another value.

If the field does not exist JlrsError::NoSuchField is returned. If allocating is required to return the field, JlrsError::NotAPointerField is returned.

This function is unsafe because the value returned as a result will only be valid as long as the field is not changed.

pub fn get_field<'fr, N, F>(
    self,
    frame: &mut F,
    field_name: N
) -> JlrsResult<Value<'fr, 'data>> where
    N: TemporarySymbol,
    F: Frame<'fr>, 
[src]

Returns the field with the name field_name if it exists. If it does not exist JlrsError::NoSuchField is returned. This function assumes the field must be protected from garbage collection, so calling this function will take a single slot on the GC stack. If there is no slot available JlrsError::AllocError is returned.

pub fn get_field_output<'output, 'fr, N, F>(
    self,
    frame: &mut F,
    output: Output<'output>,
    field_name: N
) -> JlrsResult<Value<'output, 'data>> where
    N: TemporarySymbol,
    F: Frame<'fr>, 
[src]

Returns the field with the name field_name if it exists. If it does not exist JlrsError::NoSuchField is returned. This function assumes the field must be protected from garbage collection and uses the provided output to do so.

pub unsafe fn get_field_noalloc<N>(
    self,
    field_name: N
) -> JlrsResult<Value<'frame, 'data>> where
    N: TemporarySymbol
[src]

Returns the field with the name field_name if it exists and no allocation is required to return it. Allocation is not required if the field is a pointer to another value.

If the field does not exist JlrsError::NoSuchField is returned. If allocating is required to return the field, JlrsError::NotAPointerField is returned.

This function is unsafe because the value returned as a result will only be valid as long as the field is not changed.

pub unsafe fn set_nth_field(
    self,
    idx: usize,
    value: Value<'_, '_>
) -> JlrsResult<()>
[src]

Set the value of the field at idx. Returns an error if this value is immutable or if the type of value is not a subtype of the field type. This is unsafe because the previous value of this field can become unrooted if you're directly using it from Rust.

pub unsafe fn assume_owned(self) -> Value<'frame, 'static>[src]

If you call a function with one or more borrowed arrays as arguments, its result can only be used when all the borrows are active. If this result doesn't reference any borrowed data this function can be used to relax its second lifetime to 'static.

Safety: The value must not contain a reference any borrowed data.

pub fn extend<'output, F>(
    self,
    frame: &mut F,
    output: Output<'output>
) -> Value<'output, 'data> where
    F: Frame<'frame>, 
[src]

Extend the Value's lifetime to the Output's lifetime. The original value will still be valid after calling this method, the data will be protected from garbage collection until the Output`'s frame goes out of scope.

pub fn subtype(self, sup: Value<'_, '_>) -> bool[src]

Returns true if self is a subtype of sup.

pub fn is_kind(self) -> bool[src]

Returns true if self is the type of a DataType, UnionAll, Union, or Union{} (the bottom type).

pub fn is_type(self) -> bool[src]

Returns true if the value is a type, ie a DataType, UnionAll, Union, or Union{} (the bottom type).

pub fn new_array<T, D, F>(
    frame: &mut F,
    dimensions: D
) -> JlrsResult<Value<'frame, 'static>> where
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    F: Frame<'frame>, 
[src]

Allocates a new n-dimensional array in Julia.

Creating an an array with 1, 2 or 3 dimensions requires one slot on the GC stack. If you create an array with more dimensions an extra frame is created with a single slot, temporarily taking 3 additional slots.

This function returns an error if there are not enough slots available.

pub fn new_array_output<'output, T, D, F>(
    frame: &mut F,
    output: Output<'output>,
    dimensions: D
) -> JlrsResult<Value<'output, 'static>> where
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    F: Frame<'frame>, 
[src]

Allocates a new n-dimensional array in Julia using an Output.

Because an Output is used, no additional slot in the current frame is used if you create an array with 1, 2 or 3 dimensions. If you create an array with more dimensions an extra

This function returns an error if there are not enough slots available.

pub fn borrow_array<T, D, V, F>(
    frame: &mut F,
    data: &'data mut V,
    dimensions: D
) -> JlrsResult<Value<'frame, 'data>> where
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    V: BorrowMut<[T]>,
    F: Frame<'frame>, 
[src]

Borrows an n-dimensional array from Rust for use in Julia.

Borrowing an array with one dimension requires one slot on the GC stack. If you borrow an array with more dimensions, an extra frame is created with a single slot slot, temporarily taking 3 additional slots.

This function returns an error if there are not enough slots available.

pub fn borrow_array_output<'output, 'borrow, T, D, V, F>(
    frame: &mut F,
    output: Output<'output>,
    data: &'borrow mut V,
    dimensions: D
) -> JlrsResult<Value<'output, 'borrow>> where
    'borrow: 'output,
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    V: BorrowMut<[T]>,
    F: Frame<'frame>, 
[src]

Borrows an n-dimensional array from Rust for use in Julia using an Output.

Because an Output is used, no additional slot in the current frame is used for the array itself. If you borrow an array with more than 1 dimension an extra frame is created with a single slot, temporarily taking 3 additional slots.

This function returns an error if there are not enough slots available.

pub fn move_array<T, D, F>(
    frame: &mut F,
    data: Vec<T>,
    dimensions: D
) -> JlrsResult<Value<'frame, 'static>> where
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    F: Frame<'frame>, 
[src]

Moves an n-dimensional array from Rust to Julia.

Moving an array with one dimension requires one slot on the GC stack. If you move an array with more dimensions, an extra frame is created with a single slot slot, temporarily taking 3 additional slots.

This function returns an error if there are not enough slots available.

pub fn move_array_output<'output, T, D, F>(
    frame: &mut F,
    output: Output<'output>,
    data: Vec<T>,
    dimensions: D
) -> JlrsResult<Value<'output, 'static>> where
    T: IntoJulia + JuliaType,
    D: Into<Dimensions>,
    F: Frame<'frame>, 
[src]

Moves an n-dimensional array from Rust to Julia using an output.

Because an Output is used, no additional slot in the current frame is used for the array itself. If you move an array with more dimensions, an extra frame is created with a single slot slot, temporarily taking 3 additional slots.

This function returns an error if there are not enough slots available.

pub fn with_output<'output>(
    self,
    output: Output<'output>
) -> WithOutput<'output, Value<'frame, 'data>>
[src]

Wraps a Value so that a function call will not require a slot in the current frame but uses the one that was allocated for the output.

pub fn call0<F>(self, frame: &mut F) -> JlrsResult<CallResult<'frame, 'static>> where
    F: Frame<'frame>, 
[src]

Call this value as a function that takes zero arguments, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub fn call1<'borrow, F>(
    self,
    frame: &mut F,
    arg: Value<'_, 'borrow>
) -> JlrsResult<CallResult<'frame, 'borrow>> where
    F: Frame<'frame>, 
[src]

Call this value as a function that takes one argument, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub fn call2<'borrow, F>(
    self,
    frame: &mut F,
    arg0: Value<'_, 'borrow>,
    arg1: Value<'_, 'borrow>
) -> JlrsResult<CallResult<'frame, 'borrow>> where
    F: Frame<'frame>, 
[src]

Call this value as a function that takes two arguments, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub fn call3<'borrow, F>(
    self,
    frame: &mut F,
    arg0: Value<'_, 'borrow>,
    arg1: Value<'_, 'borrow>,
    arg2: Value<'_, 'borrow>
) -> JlrsResult<CallResult<'frame, 'borrow>> where
    F: Frame<'frame>, 
[src]

Call this value as a function that takes three arguments, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub fn call<'value, 'borrow, V, F>(
    self,
    frame: &mut F,
    args: V
) -> JlrsResult<CallResult<'frame, 'borrow>> where
    V: AsMut<[Value<'value, 'borrow>]>,
    F: Frame<'frame>, 
[src]

Call this value as a function that takes several arguments, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub async fn call_async<'value, 'borrow, V, '_>(
    self,
    frame: &'_ mut AsyncFrame<'frame>,
    args: V
) -> JlrsResult<CallResult<'frame, 'borrow>> where
    V: AsMut<[Value<'value, 'borrow>]>, 
[src]

Call this value as a function that takes several arguments and execute it on another thread in Julia created with Base.@spawn, this takes two slots on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

This function can only be called with an AsyncFrame, while you're waiting for this function to complete, other tasks are able to progress.

pub fn call_values<F>(
    self,
    frame: &mut F,
    args: Values<'_>
) -> JlrsResult<CallResult<'frame, 'static>> where
    F: Frame<'frame>, 
[src]

Call this value as a function that takes several arguments in a single Values, this takes one slot on the GC stack. Returns the result of this function call if no exception is thrown, the exception if one is, or an error if no space is left on the stack.

pub fn tracing_call<F>(
    self,
    frame: &mut F
) -> JlrsResult<CallResult<'frame, 'data>> where
    F: Frame<'frame>, 
[src]

Returns an anonymous function that wraps this value in a try-catch block. Calling this anonymous function with some arguments will call the value as a function with those arguments and return its result, or catch the exception, print the stackstrace, and rethrow that exception. This takes one slot on the GC stack. You must include jlrs.jl to use this function.

pub fn attach_stacktrace<F>(
    self,
    frame: &mut F
) -> JlrsResult<CallResult<'frame, 'data>> where
    F: Frame<'frame>, 
[src]

Returns an anonymous function that wraps this value in a try-catch block. Calling this anonymous function with some arguments will call the value as a function with those arguments and return its result, or catch the exception and throw a new one with two fields, exc and stacktrace, containing the original exception and the stacktrace respectively. This takes one slot on the GC stack. You must include jlrs.jl to use this function.

Trait Implementations

impl<'frame, 'data> Clone for Value<'frame, 'data>[src]

impl<'frame, 'data> Copy for Value<'frame, 'data>[src]

impl<'frame, 'data> Debug for Value<'frame, 'data>[src]

impl<'base> Into<Value<'base, 'static>> for Module<'base>[src]

impl<'base> Into<Value<'base, 'static>> for Symbol<'base>[src]

impl<'frame, 'data> Into<Value<'frame, 'data>> for Array<'frame, 'data>[src]

impl<'frame, 'data, T: Copy + ValidLayout> Into<Value<'frame, 'data>> for TypedArray<'frame, 'data, T>[src]

impl<'frame> Into<Value<'frame, 'static>> for CodeInstance<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for DataType<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for TypeVar<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for TypeMapEntry<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for TypeMapLevel<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for Union<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for UnionAll<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for WeakRef<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for Expr<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for Method<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for MethodInstance<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for MethodTable<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for SimpleVector<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for JuliaString<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for Task<'frame>[src]

impl<'frame> Into<Value<'frame, 'static>> for TypeName<'frame>[src]

impl<'frame, 'data> JuliaType for Value<'frame, 'data>[src]

impl<'frame, 'data> ValidLayout for Value<'frame, 'data>[src]

Auto Trait Implementations

impl<'frame, 'data> RefUnwindSafe for Value<'frame, 'data>

impl<'frame, 'data> !Send for Value<'frame, 'data>

impl<'frame, 'data> !Sync for Value<'frame, 'data>

impl<'frame, 'data> Unpin for Value<'frame, 'data>

impl<'frame, 'data> UnwindSafe for Value<'frame, 'data>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.