Skip to main content

photon_ring/
pod.rs

1// Copyright 2026 Photon Ring Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4//! The [`Pod`] marker trait for seqlock-safe payload types.
5
6/// Marker trait for types safe to use with seqlock-stamped ring buffers.
7///
8/// A type is `Pod` ("Plain Old Data") if **every possible bit pattern**
9/// of `size_of::<T>()` bytes represents a valid value of `T`. This is
10/// stricter than [`Copy`] — it excludes types where certain bit patterns
11/// are undefined behavior, such as `bool` (only 0/1 valid), `char`
12/// (must be a valid Unicode scalar), `NonZero*` (must be nonzero), and
13/// references (must point to valid memory).
14///
15/// # Why this matters
16///
17/// The seqlock read protocol performs an optimistic non-atomic read that
18/// may observe a partially-written ("torn") value. If the torn bit pattern
19/// violates a type's validity invariant, this is undefined behavior even
20/// though the value is detected and discarded by the stamp check. `Pod`
21/// guarantees that no bit pattern is invalid, making torn reads harmless.
22///
23/// # Safety
24///
25/// Implementors must ensure:
26/// 1. `T` is `Copy` (no destructor, no move semantics).
27/// 2. `T` is `Send` (safe to transfer across threads).
28/// 3. Every possible bit pattern of `size_of::<T>()` bytes is a valid `T`.
29/// 4. `T` has no padding bytes that carry validity constraints.
30///
31/// # Pre-implemented types
32///
33/// `Pod` is implemented for all primitive numeric types, arrays of `Pod`
34/// types, and tuples up to 12 elements of `Pod` types.
35///
36/// For user-defined structs, use `unsafe impl`:
37/// ```
38/// #[repr(C)]
39/// #[derive(Clone, Copy)]
40/// struct Quote {
41///     price: f64,
42///     volume: u32,
43///     _pad: u32,
44/// }
45///
46/// // SAFETY: Quote is #[repr(C)], all fields are plain numerics,
47/// // and every bit pattern is a valid Quote.
48/// unsafe impl photon_ring::Pod for Quote {}
49/// ```
50pub unsafe trait Pod: Copy + Send + 'static {}
51
52// Primitive numeric types — every bit pattern is valid
53unsafe impl Pod for u8 {}
54unsafe impl Pod for u16 {}
55unsafe impl Pod for u32 {}
56unsafe impl Pod for u64 {}
57unsafe impl Pod for u128 {}
58unsafe impl Pod for i8 {}
59unsafe impl Pod for i16 {}
60unsafe impl Pod for i32 {}
61unsafe impl Pod for i64 {}
62unsafe impl Pod for i128 {}
63unsafe impl Pod for f32 {}
64unsafe impl Pod for f64 {}
65unsafe impl Pod for usize {}
66unsafe impl Pod for isize {}
67
68// Arrays of Pod types
69unsafe impl<T: Pod, const N: usize> Pod for [T; N] {}
70
71// Tuples of Pod types (up to 12, matching standard library convention)
72unsafe impl Pod for () {}
73unsafe impl<A: Pod> Pod for (A,) {}
74unsafe impl<A: Pod, B: Pod> Pod for (A, B) {}
75unsafe impl<A: Pod, B: Pod, C: Pod> Pod for (A, B, C) {}
76unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod> Pod for (A, B, C, D) {}
77unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod> Pod for (A, B, C, D, E) {}
78unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod> Pod for (A, B, C, D, E, F) {}
79unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod, G: Pod> Pod for (A, B, C, D, E, F, G) {}
80unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod, G: Pod, H: Pod> Pod
81    for (A, B, C, D, E, F, G, H)
82{
83}
84unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod, G: Pod, H: Pod, I: Pod> Pod
85    for (A, B, C, D, E, F, G, H, I)
86{
87}
88unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod, G: Pod, H: Pod, I: Pod, J: Pod> Pod
89    for (A, B, C, D, E, F, G, H, I, J)
90{
91}
92unsafe impl<A: Pod, B: Pod, C: Pod, D: Pod, E: Pod, F: Pod, G: Pod, H: Pod, I: Pod, J: Pod, K: Pod>
93    Pod for (A, B, C, D, E, F, G, H, I, J, K)
94{
95}
96unsafe impl<
97        A: Pod,
98        B: Pod,
99        C: Pod,
100        D: Pod,
101        E: Pod,
102        F: Pod,
103        G: Pod,
104        H: Pod,
105        I: Pod,
106        J: Pod,
107        K: Pod,
108        L: Pod,
109    > Pod for (A, B, C, D, E, F, G, H, I, J, K, L)
110{
111}