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