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.reflect
— Functionreflect(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,
}
JlrsReflect.renamestruct!
— Functionrenamestruct!(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 {
}
JlrsReflect.renamefields!
— Functionrenamefields!(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,
}