vortex_flatbuffers/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! A contiguously serialized Vortex array.
5//!
6//! See the `vortex-file` crate for non-contiguous serialization.
7
8#![deny(missing_docs)]
9
10#[cfg(feature = "array")]
11#[allow(clippy::all)]
12#[allow(clippy::derive_partial_eq_without_eq)]
13#[allow(clippy::many_single_char_names)]
14#[allow(clippy::unwrap_used)]
15#[allow(clippy::borrow_as_ptr)]
16#[allow(dead_code)]
17// TODO(robert): Remove once we can update toolchain
18#[allow(unknown_lints)]
19#[allow(mismatched_lifetime_syntaxes)]
20#[allow(non_snake_case)]
21#[allow(non_camel_case_types)]
22#[allow(unsafe_op_in_unsafe_fn)]
23#[allow(unused_imports)]
24#[allow(unused_lifetimes)]
25#[allow(unused_qualifications)]
26#[allow(missing_docs)]
27#[rustfmt::skip]
28#[path = "./generated/array.rs"]
29/// A serialized array without its buffer (i.e. data).
30///
31/// `array.fbs`:
32/// ```flatbuffers
33#[doc = include_str!("../flatbuffers/vortex-array/array.fbs")]
34/// ```
35pub mod array;
36
37#[cfg(feature = "dtype")]
38#[allow(clippy::all)]
39#[allow(clippy::derive_partial_eq_without_eq)]
40#[allow(clippy::many_single_char_names)]
41#[allow(clippy::unwrap_used)]
42#[allow(clippy::borrow_as_ptr)]
43#[allow(dead_code)]
44// TODO(robert): Remove once we can update toolchain
45#[allow(unknown_lints)]
46#[allow(mismatched_lifetime_syntaxes)]
47#[allow(non_snake_case)]
48#[allow(non_camel_case_types)]
49#[allow(unsafe_op_in_unsafe_fn)]
50#[allow(unused_imports)]
51#[allow(unused_lifetimes)]
52#[allow(unused_qualifications)]
53#[allow(missing_docs)]
54#[rustfmt::skip]
55#[path = "./generated/dtype.rs"]
56/// A serialized data type.
57///
58/// `dtype.fbs`:
59/// ```flatbuffers
60#[doc = include_str!("../flatbuffers/vortex-dtype/dtype.fbs")]
61/// ```
62pub mod dtype;
63
64#[cfg(feature = "file")]
65#[allow(clippy::all)]
66#[allow(clippy::derive_partial_eq_without_eq)]
67#[allow(clippy::many_single_char_names)]
68#[allow(clippy::unwrap_used)]
69#[allow(clippy::borrow_as_ptr)]
70#[allow(dead_code)]
71// TODO(robert): Remove once we can update toolchain
72#[allow(unknown_lints)]
73#[allow(mismatched_lifetime_syntaxes)]
74#[allow(non_snake_case)]
75#[allow(non_camel_case_types)]
76#[allow(unsafe_op_in_unsafe_fn)]
77#[allow(unused_imports)]
78#[allow(unused_lifetimes)]
79#[allow(unused_qualifications)]
80#[allow(missing_docs)]
81#[rustfmt::skip]
82#[path = "./generated/footer.rs"]
83/// A file format footer containing a serialized `vortex-file` Layout.
84///
85/// `footer.fbs`:
86/// ```flatbuffers
87#[doc = include_str!("../flatbuffers/vortex-file/footer.fbs")]
88/// ```
89pub mod footer;
90
91#[cfg(feature = "layout")]
92#[allow(clippy::all)]
93#[allow(clippy::derive_partial_eq_without_eq)]
94#[allow(clippy::many_single_char_names)]
95#[allow(clippy::unwrap_used)]
96#[allow(clippy::borrow_as_ptr)]
97#[allow(dead_code)]
98// TODO(robert): Remove once we can update toolchain
99#[allow(unknown_lints)]
100#[allow(mismatched_lifetime_syntaxes)]
101#[allow(non_snake_case)]
102#[allow(non_camel_case_types)]
103#[allow(unsafe_op_in_unsafe_fn)]
104#[allow(unused_imports)]
105#[allow(unused_lifetimes)]
106#[allow(unused_qualifications)]
107#[allow(missing_docs)]
108#[rustfmt::skip]
109#[path = "./generated/layout.rs"]
110/// Structures describing the physical layout of Vortex arrays in random access storage.
111///
112/// `layout.fbs`:
113/// ```flatbuffers
114#[doc = include_str!("../flatbuffers/vortex-layout/layout.fbs")]
115/// ```
116pub mod layout;
117
118#[cfg(feature = "ipc")]
119#[allow(clippy::all)]
120#[allow(clippy::derive_partial_eq_without_eq)]
121#[allow(clippy::many_single_char_names)]
122#[allow(clippy::unwrap_used)]
123#[allow(clippy::borrow_as_ptr)]
124#[allow(dead_code)]
125// TODO(robert): Remove once we can update toolchain
126#[allow(unknown_lints)]
127#[allow(mismatched_lifetime_syntaxes)]
128#[allow(non_snake_case)]
129#[allow(non_camel_case_types)]
130#[allow(unsafe_op_in_unsafe_fn)]
131#[allow(unused_imports)]
132#[allow(unused_lifetimes)]
133#[allow(unused_qualifications)]
134#[allow(missing_docs)]
135#[rustfmt::skip]
136#[path = "./generated/message.rs"]
137/// A serialized sequence of arrays, each with its buffers.
138///
139/// `message.fbs`:
140/// ```flatbuffers
141#[doc = include_str!("../flatbuffers/vortex-serde/message.fbs")]
142/// ```
143pub mod message;
144
145use flatbuffers::{FlatBufferBuilder, Follow, InvalidFlatbuffer, Verifiable, WIPOffset, root};
146use vortex_buffer::{ByteBuffer, ConstByteBuffer};
147
148/// We define a const-aligned byte buffer for flatbuffers with 8-byte alignment.
149///
150/// This is based on the assumption that the maximum primitive type is 8 bytes.
151/// See: <https://groups.google.com/g/flatbuffers/c/PSgQeWeTx_g>
152pub type FlatBuffer = ConstByteBuffer<8>;
153
154/// Marker trait for types that can be the root of a FlatBuffer.
155pub trait FlatBufferRoot {}
156
157/// Trait for reading a type from a FlatBuffer.
158pub trait ReadFlatBuffer: Sized {
159    /// The FlatBuffer type that this type can be read from.
160    type Source<'a>: Verifiable + Follow<'a>;
161    /// The error type returned when reading fails.
162    type Error: From<InvalidFlatbuffer>;
163
164    /// Reads this type from a FlatBuffer source.
165    fn read_flatbuffer<'buf>(
166        fb: &<Self::Source<'buf> as Follow<'buf>>::Inner,
167    ) -> Result<Self, Self::Error>;
168
169    /// Reads this type from bytes representing a FlatBuffer source.
170    fn read_flatbuffer_bytes<'buf>(bytes: &'buf [u8]) -> Result<Self, Self::Error>
171    where
172        <Self as ReadFlatBuffer>::Source<'buf>: 'buf,
173    {
174        let fb = root::<Self::Source<'buf>>(bytes)?;
175        Self::read_flatbuffer(&fb)
176    }
177}
178
179/// Trait for writing a type to a FlatBuffer.
180pub trait WriteFlatBuffer {
181    /// The FlatBuffer type that this type can be written to.
182    type Target<'a>;
183
184    /// Writes this type to a FlatBuffer builder.
185    fn write_flatbuffer<'fb>(
186        &self,
187        fbb: &mut FlatBufferBuilder<'fb>,
188    ) -> WIPOffset<Self::Target<'fb>>;
189}
190
191/// Extension trait for types that can be written as FlatBuffer root objects.
192pub trait WriteFlatBufferExt: WriteFlatBuffer + FlatBufferRoot {
193    /// Writes self as a FlatBuffer root object into a [`FlatBuffer`] byte buffer.
194    fn write_flatbuffer_bytes(&self) -> FlatBuffer;
195}
196
197impl<F: WriteFlatBuffer + FlatBufferRoot> WriteFlatBufferExt for F {
198    fn write_flatbuffer_bytes(&self) -> FlatBuffer {
199        let mut fbb = FlatBufferBuilder::new();
200        let root_offset = self.write_flatbuffer(&mut fbb);
201        fbb.finish_minimal(root_offset);
202        let (vec, start) = fbb.collapse();
203        let end = vec.len();
204        FlatBuffer::align_from(ByteBuffer::from(vec).slice(start..end))
205    }
206}