type_slicer

Crates.iotype_slicer
lib.rstype_slicer
version0.3.0
created_at2025-12-06 10:19:49.857722+00
updated_at2026-01-06 13:30:26.032126+00
description型付きメモリスライサー
homepage
repository
max_upload_size
id1969942
size46,366
ShizukaKokoro (ShizukaKokoro)

documentation

README

TypeSlicer

TypeSlicer は任意のバイト列ストレージを「型付きメモリアクセス層」に昇格させる Rust 2024 Edition 向けクレートです。 repr::ByteRepr で型のバイト表現を定義し、storage::BytesStorage でストレージの読み書き方法を与えることで、Slicer<T>load / store だけで安全に値を交換できます。

コアコンポーネント

repr::ByteRepr

  • const SIZE: usize / into_bytes(self, buf: &mut [u8]) / from_bytes(bytes: &[u8]) -> Result<Self, ReprError> を持つトレイト。
  • SIZE はコンパイル時計算できます。
  • ReprError::InvalidByteValue を返すことでスカラー値の検証(例: bool が 0/1 のみ)を実装。

storage::BytesStorage

  • get(address, size) / get_mut(address, size) でバイトスライスを貸し出す責務だけを負います。
  • 先読み・遅延書き込み、mmap バッファ等のバックエンドはトレイト実装で差し替え可能です。

Slicer<T>

  • BytesStorage を実装した任意の型に対し、T: ByteRepr について blanket impl を提供。
  • load(address)BytesStorage::getByteRepr::from_bytes を連結し、store(address, value)get_mutinto_bytes を呼び出します。

インストール

[dependencies]
type_slicer = { version = "0.1" }

no_std で使う

[dependencies]
type_slicer = { version = "0.1", default-features = false }
  • std feature (default) は alloc を自動的に有効化します。
  • alloc なしの場合は ArrayStorage など固定長ストレージのみを利用できます。

付属ストレージ実装

  • ArrayStorage<const N: usize>: no_std でも利用できる固定長ストレージ。new() / Default は 0 埋めで初期化します。
  • VecStorage (alloc 必須): 任意長で確保し、resize(new_len) で後からサイズ変更できます。

どちらも BytesStorage を実装しているため、そのまま Slicer<T> として利用できます。独自ストレージを追加したい場合は get / get_mut を実装するだけで load / store が自動で解放されます。

ByteRepr を自作する

repr::ByteRepr は公開トレイトなので、ユーザ定義型をタプルや配列に委譲して簡単に実装できます。

use type_slicer::ByteRepr;

#[derive(Clone, Copy, Debug, PartialEq, ByteRepr)]
struct Header {
    kind: u8,
    has_payload: bool,
    payload_len: u16,
}

バイトの長さは常に SIZE と等しいことはこの外側で保証されているため、境界チェックは不要です。 もし、 Slicer を使わずに直接呼び出す場合は、呼び出し側で長さを検証してください。

使用例

use type_slicer::{Slicer, VecStorage, ByteRepr};

#[derive(Clone, Copy, Debug, PartialEq, ByteRepr)]
struct Packet {
    opcode: u8,
    has_body: bool,
    length: u16,
}

fn main() -> Result<(), type_slicer::slicer::SlicerError> {
    let mut storage = VecStorage::new(32);

    storage.store(0, 0xDEAD_BEEFu32)?;
    storage.store(4, [1u16, 2, 3, 4])?;
    storage.store(12, Packet { opcode: 7, has_body: true, length: 16 })?;

    let header: u32 = storage.load(0)?;
    let payload: [u16; 4] = storage.load(4)?;
    let packet: Packet = storage.load(12)?;

    assert_eq!(header, 0xDEAD_BEEF);
    assert_eq!(payload, [1, 2, 3, 4]);
    assert_eq!(packet.length, 16);
    Ok(())
}

制限と設計上の割り切り

  • 動的サイズ型は ByteRepr を実装できません。
  • 参照やポインタを扱う場合はアドレスそのもの (usize) をどのように解釈するかをアプリケーション側で規定してください。
  • speed feature を有効化すると、bool / char の検証をスキップするため未定義値が発生し得ます。
Commit count: 0

cargo fmt