Skip to main content

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