array-as-struct 0.1.0

A crate to make ergonomic "field" accesses on array types
Documentation
  • Coverage
  • 100%
    13 out of 13 items documented5 out of 8 items with examples
  • Size
  • Source code size: 24.51 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 684.13 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 12s Average build duration of successful builds.
  • all releases: 12s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Daniel-Aaron-Bloom/array-as-struct
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • Daniel-Aaron-Bloom

Array As Struct

A crate to make ergonomic "field" accesses on array types.

Motivation

Sometimes you're working with APIs which take in slices or arrays, but your code would better served by named fields. An example of this might be an API which takes [u8; 3] for colors, but you'd prefer to have

struct Color{ r: u8, g: u8, b: u8 }

One solution is to use repr(C) and transmute or a union, but that obviously precludes forbid(unsafe_code).

A safer option is to instead use an enum to represent each field, which can be done with crates like enum-map. This is much better, but involves using macros to construct the type, and sometimes the indexing operations and enum-variant resolution obstruct the readability of code.

use enum_map::{EnumMap, Enum};

#[derive(Debug, Enum)]
enum ColorType {
    R,
    G,
    B,
}

type Color = EnumMap<ColorType, u8>;

let mut color: Color = enum_map! {
    Example::R => 247,
    Example::G => 0,
    Example::B => 0,
};
color[Example::G] = 76;

This crate provides an alternative approach, relying on helper structs to bridge the gap between the array type and the field-based struct type.

use array_as_struct::{array_as_struct, ArrayStruct};

#[array_as_struct]
// Despite this declaration, `Color` is actual a tuple struct
// which looks like `struct Color([u8; 3]);`
pub struct Color {
    r: u8,
    g: u8,
    b: u8,
}

// This is the actual named-field struct
type ColorValue = <Color as ArrayStruct>::Value;

let mut color = Color::from_val(ColorValue { r: 247, g: 0, b: 0 });
*f.muts().g = 76;

FAQ

  • Why replace the original declaration with a array-based tuple struct? Why not just add the array-struct as a derived type?

The main motivation of this crate is to help people deal with [T] APIs. By hiding the original field-based struct, this crate makes the array-based type the default, encouraging users to treat the field-based struct purely as a short-lived ergonomic tool for referencing "fields" by name.