JlrsReflect.jl Documentation

One of the main features of jlrs is the possibility to easily convert data from Julia to Rust. By default only a few builtin types, like integers, arrays and modules are available, but this can be extended by using the derive macro from jlrs-derive. One annoying aspect of these macros is that you need to figure out the correct layout first.

With JlrsReflect.jl you can automatically generate wrappers for many Julia types that are compatible with jlrs 0.11. This includes types with unions, tuples, and type parameters. Even value types are not a problem because the wrappers only contain type parameters that directly affect the layout. If a field contains pointers, the Ref types from jlrs are used. Two things that are not supported are structs with union or tuple fields that depend on a type parameter (eg struct SomeGenericStruct{T} a::Tuple{Int32, T} end, SomeGenericStruct{T} a::Union{Int32, T} end), and unions used as generic parameters (eg SomeGenericStruct{Union{A,B}}).

JlrsReflect.reflectFunction
reflect(types::Vector{<:Type})::Wrappers

Generate Rust wrappers for all types in types and their dependencies. The only requirement is that these types must not contain any union or tuple fields that depend on a type parameter. Wrappers are generated for the most general case by erasing the contents of all provided type parameters, so you can't avoid this restriction by explicitly providing a more qualified type. The only effect qualifying types has, is that wrappers for the used parameters will also be generated. The wrappers will derive Unbox and ValidLayout, and IntoJulia if it's a bits-type with no type parameters.

The result of this function can be written to a file, its contents will normally be a valid Rust module.

When you use these wrappers with jlrs, these types must be available with the same path. For example, if you generate wrappers for Main.Bar.Baz, this type must be available through that exact path and not some other path like Main.Foo.Bar.Baz.

Example

julia> using JlrsReflect

julia> reflect([Complex])
#[repr(C)]
#[derive(Clone, Debug, Unbox, ValidLayout, Typecheck)]
#[jlrs(julia_type = "Base.Complex")]
pub struct Complex<T>
where
    T: ::jlrs::layout::valid_layout::ValidLayout + Clone,
{
    pub re: T,
    pub im: T,
}
source
JlrsReflect.renamestruct!Function
renamestruct!(wrappers::Wrappers, type::Type, rename::String)

Change a struct's name. This can be useful if the name of a struct results in invalid Rust code or causes warnings.

Example

julia> using JlrsReflect

julia> struct Foo end

julia> wrappers = reflect([Foo]);

julia> renamestruct!(wrappers, Foo, "Bar")

julia> wrappers
#[repr(C)]
#[derive(Clone, Debug, Unbox, ValidLayout, Typecheck, IntoJulia)]
#[jlrs(julia_type = "Main.Foo", zero_sized_type)]
pub struct Bar {
}
source
JlrsReflect.renamefields!Function
renamefields!(wrappers::Wrappers, type::Type, rename::Dict{Symbol,String})
renamefields!(wrappers::Wrappers, type::Type, rename::Vector{Pair{Symbol,String})

Change some field names of a struct. This can be useful if the name of a struct results in invalid Rust code or causes warnings.

Example

julia> using JlrsReflect

julia> struct Food burger::Bool end

julia> wrappers = reflect([Food]);

julia> renamefields!(wrappers, Food, [:burger => "hamburger"])

julia> wrappers
#[repr(C)]
#[derive(Clone, Debug, Unbox, ValidLayout, Typecheck, IntoJulia)]
#[jlrs(julia_type = "Main.Food")]
pub struct Food {
    pub hamburger: ::jlrs::wrappers::inline::bool::Bool,
}
source