This crate allows you to safely initialize Dynamically Sized Types (DST) using only safe Rust.

Overview

Crates.io docs.rs

dyn_struct

This crate allows you to safely initialize Dynamically Sized Types (DST) using only safe Rust.

#[repr(C)]
#[derive(DynStruct)]
struct MyDynamicType {
    pub awesome: bool,
    pub number: u32,
    pub dynamic: [u32],
}

// the `new` function is generated by the `DynStruct` macro.
let foo: Box<MyDynamicType> = MyDynamicType::new(true, 123, &[4, 5, 6, 7]);
assert_eq!(foo.awesome, true);
assert_eq!(foo.number, 123);
assert_eq!(&foo.dynamic, &[4, 5, 6, 7]);

Why Dynamic Types?

In Rust, Dynamically Sized Types (DST) are everywhere. Slices ([T]) and trait objects (dyn Trait) are the most common ones. However, it is also possible to define your own! For example, this can be done by letting the last field in a struct be a dynamically sized array (note the missing &):

struct MyDynamicType {
    awesome: bool,
    number: u32,
    dynamic: [u32],
}

This tells the Rust compiler that contents of the dynamic-array is laid out in memory right after the other fields. This can be very preferable in some cases, since remove one level of indirection and increase cache-locality.

However, there's a catch! Just as with slices, the compiler does not know how many elements are in dynamic. Thus, we need what is called a fat-pointer which stores both a pointer to the actual data, but also the length of the array itself. As of releasing this crate, the only safe way to construct a dynamic type is if we know the size of the array at compile-time. However, for most use cases, that is not possible. Therefore this crate uses some unsafe behind the scenes to work around the limitations of the language, all wrapped up in a safe interface.

The Derive Macro

The DynStruct macro can be applied to any #[repr(C)] struct that contains a dynamically sized array as its last field. Fields only have a single constraint: they have to implement Copy.

Example

#[repr(C)]
#[derive(DynStruct)]
struct MyDynamicType {
    pub awesome: bool,
    pub number: u32,
    pub dynamic: [u32],
}

will produce a single impl-block with a new function:

impl MyDynamicType {
    pub fn new(awesome: bool, number: u32, dynamic: &[u32]) -> Box
    {
        
   // ... implementation details ...
    }
}
  

Due to the nature of dynamically sized types, the resulting value has to be built on the heap. For safety reasons we currently only allow returning Box, though in a future version we may also allow Rc and Arc. In the meantime it is posible to use Arc::from(MyDynamicType::new(...)).

You might also like...
single file, std only, async Rust executor

whorl - A single file, std only, async Rust executor whorl was created to teach you how async executors work in Rust. It is not the fastest executor n

Detect if code is running inside a virtual machine (x86 and x86-64 only).

inside-vm Detect if code is running inside a virtual machine. Only works on x86 and x86-64. How does it work Measure average cpu cycles when calling c

Searchbuddy is a browser extension that lets you chat with people that are searching for what you're searching for.
Searchbuddy is a browser extension that lets you chat with people that are searching for what you're searching for.

searchbuddy Make friends while searching! Searchbuddy is a browser extension that lets you chat with people that are searching for what you're searchi

Flexcord! A custom Discord client to allow you to do what you want!

Disclaimer Flexcord is NO WHERE near done. Flexcord What is it? Flexcord is a Discord client that flexes for your needs, it allows you to do exactly w

Bongo Copy Cat wants to be involved in everything you do but instead just imitates you hitting your keyboard all day. After all it's just a cat.
Bongo Copy Cat wants to be involved in everything you do but instead just imitates you hitting your keyboard all day. After all it's just a cat.

Bongo Copy Cat Introduction Bongo Copy Cat wants to be involved in everything you do but instead just imitates you hitting your keyboard all day. Afte

A lean, minimal, and stable set of types for color interoperation between crates in Rust.

This library provides a lean, minimal, and stable set of types for color interoperation between crates in Rust. Its goal is to serve the same function that mint provides for (linear algebra) math types.

Utilities to gather data out of roms. Written in Rust. It (should) support all types.

snesutilities Utilities to gather data out of roms. Written in Rust. It (should) support all types. How Have a look at main.rs: use snesutilities::Sne

A framework for iterating over collections of types implementing a trait without virtual dispatch
A framework for iterating over collections of types implementing a trait without virtual dispatch

zero_v Zero_V is an experiment in defining behavior over collections of objects implementing some trait without dynamic polymorphism.

Time related types (and conversions) for scientific and astronomical usage.

astrotime Time related types (and conversions) for scientific and astronomical usage. This library is lightweight and high performance. Features The f

Comments
  • Copy restriction

    Copy restriction

    Can Copy restriction be lifted somehow?

    I want to use dyn_struct with intrusive-collections like:

    #[repr(C)]
    #[derive(DynStruct)]
    struct SparseComponentPtrs{
        pub link: LinkedListLink,
        pub ptrs: [Option<NonNull<u8>>]
    }
    

    But I can't, since LinkedListLink does not implement Copy.

    opened by tower120 6
  • Self with #[derive(DynStruct)]

    Self with #[derive(DynStruct)]

    Self in struct declaration with #[derive(DynStruct)] becomes "mangled" with some _DynStruct_Single:

        #[repr(C)]
        #[derive(DynStruct)]
        struct MyNode{
            pub link: ListLink<Self>,
            pub dynamic: [u32],
        }
    

    Is this possible to overcome?

    opened by tower120 2
Owner
Christofer Nolander
Christofer Nolander
A dynamically prioritizable priority queue.

bheap A generic binary max heap implementation for implementing a dynamically prioritizable priority queue. This implementation uses a vector as the u

Arindam Das 4 Sep 21, 2022
serde support for http crate types Request, Response, Uri, StatusCode, HeaderMap

serde extensions for the http crate types Allows serializing and deserializing the following types from http: Response Request HeaderMap StatusCode Ur

Andrew Toth 3 Nov 1, 2023
This crate allows writing a struct in Rust and have it derive a struct of arrays layed out in memory according to the arrow format.

Arrow2-derive - derive for Arrow2 This crate allows writing a struct in Rust and have it derive a struct of arrays layed out in memory according to th

Jorge Leitao 29 Dec 27, 2022
bevy_blender is a Bevy library that allows you to use assets created in Blender directly from the .blend file

bevy_blender bevy_blender is a Bevy library that allows you to use assets created in Blender directly from the .blend file.

Jerald Thomas 45 Jan 4, 2023
File Tree Fuzzer allows you to create a pseudo-random directory hierarchy filled with some number of files.

FTZZ File Tree Fuzzer allows you to create a pseudo-random directory hierarchy filled with some number of files. Installation $ cargo +nightly install

Alex Saveau 22 Dec 28, 2022
UnTeX is both a library and an executable that allows you to manipulate and understand TeX files.

UnTeX UnTeX is both a library and an executable that allows you to manipulate and understand TeX files. Usage Executable If you wish to use the execut

Jérome Eertmans 1 Apr 5, 2022
Twidge is a fresh approach to productivity. It integrates with your workflow and allows you to be your most productive self.

Twidge A productivity app which is an extension to your mind Twidge is a cross platform productivity app, powered by rust, tauri, prisma-client-rust T

Twidge 187 Jun 28, 2023
The lambda-chaos-extension allows you to inject faults into Lambda functions without modifying the function code.

Chaos Extension - Seamless, Universal & Lightning-Fast The lambda-chaos-extension allows you to inject faults into Lambda functions without modifying

AWS CLI Tools 5 Aug 2, 2023
Showcase for pathological compile times when using knuffel / chumsky / VERY LARGE types

netherquote Showcase for pathological compile times when using knuffel / chumsky / VERY LARGE types. How to reproduce The rust toolchain version is pi

Amos Wenger 7 Jan 1, 2023
Type-safe IPC for Tauri using GraphQL

Tauri Plugin graphql A plugin for Tauri that enables type-safe IPC through GraphQL. Install Rust [dependencies] tauri-plugin-graphql = "0.2" JavaScrip

Jonas Kruckenberg 40 Dec 29, 2022