vortex_flatbuffers/
lib.rs

1//! A contiguously serialized Vortex array.
2//!
3//! See [message] and [footer] for the flatbuffer specifications.
4//!
5//! See the `vortex-file` crate for non-contiguous serialization.
6
7#[cfg(feature = "array")]
8#[allow(clippy::all)]
9#[allow(clippy::derive_partial_eq_without_eq)]
10#[allow(clippy::many_single_char_names)]
11#[allow(clippy::unwrap_used)]
12#[allow(clippy::borrow_as_ptr)]
13#[allow(dead_code)]
14#[allow(non_snake_case)]
15#[allow(non_camel_case_types)]
16#[allow(unsafe_op_in_unsafe_fn)]
17#[allow(unused_imports)]
18#[allow(unused_lifetimes)]
19#[allow(unused_qualifications)]
20#[rustfmt::skip]
21#[path = "./generated/array.rs"]
22/// A serialized array without its buffer (i.e. data).
23///
24/// `array.fbs`:
25/// ```flatbuffers
26#[doc = include_str!("../flatbuffers/vortex-array/array.fbs")]
27/// ```
28pub mod array;
29
30#[cfg(feature = "dtype")]
31#[allow(clippy::all)]
32#[allow(clippy::derive_partial_eq_without_eq)]
33#[allow(clippy::many_single_char_names)]
34#[allow(clippy::unwrap_used)]
35#[allow(clippy::borrow_as_ptr)]
36#[allow(dead_code)]
37#[allow(non_snake_case)]
38#[allow(non_camel_case_types)]
39#[allow(unsafe_op_in_unsafe_fn)]
40#[allow(unused_imports)]
41#[allow(unused_lifetimes)]
42#[allow(unused_qualifications)]
43#[rustfmt::skip]
44#[path = "./generated/dtype.rs"]
45/// A serialized data type.
46///
47/// `dtype.fbs`:
48/// ```flatbuffers
49#[doc = include_str!("../flatbuffers/vortex-dtype/dtype.fbs")]
50/// ```
51pub mod dtype;
52
53#[cfg(feature = "scalar")]
54#[allow(clippy::all)]
55#[allow(clippy::derive_partial_eq_without_eq)]
56#[allow(clippy::many_single_char_names)]
57#[allow(clippy::unwrap_used)]
58#[allow(clippy::borrow_as_ptr)]
59#[allow(dead_code)]
60#[allow(non_snake_case)]
61#[allow(non_camel_case_types)]
62#[allow(unsafe_op_in_unsafe_fn)]
63#[allow(unused_imports)]
64#[allow(unused_lifetimes)]
65#[allow(unused_qualifications)]
66#[rustfmt::skip]
67#[path = "./generated/scalar.rs"]
68/// A serialized scalar.
69///
70/// `scalar.fbs`:
71/// ```flatbuffers
72#[doc = include_str!("../flatbuffers/vortex-scalar/scalar.fbs")]
73/// ```
74pub mod scalar;
75
76#[cfg(feature = "file")]
77#[allow(clippy::all)]
78#[allow(clippy::derive_partial_eq_without_eq)]
79#[allow(clippy::many_single_char_names)]
80#[allow(clippy::unwrap_used)]
81#[allow(clippy::borrow_as_ptr)]
82#[allow(dead_code)]
83#[allow(non_snake_case)]
84#[allow(non_camel_case_types)]
85#[allow(unsafe_op_in_unsafe_fn)]
86#[allow(unused_imports)]
87#[allow(unused_lifetimes)]
88#[allow(unused_qualifications)]
89#[rustfmt::skip]
90#[path = "./generated/footer.rs"]
91/// A file format footer containing a serialized `vortex-file` Layout.
92///
93/// `footer.fbs`:
94/// ```flatbuffers
95#[doc = include_str!("../flatbuffers/vortex-file/footer.fbs")]
96/// ```
97pub mod footer;
98
99#[cfg(feature = "layout")]
100#[allow(clippy::all)]
101#[allow(clippy::derive_partial_eq_without_eq)]
102#[allow(clippy::many_single_char_names)]
103#[allow(clippy::unwrap_used)]
104#[allow(clippy::borrow_as_ptr)]
105#[allow(dead_code)]
106#[allow(non_snake_case)]
107#[allow(non_camel_case_types)]
108#[allow(unsafe_op_in_unsafe_fn)]
109#[allow(unused_imports)]
110#[allow(unused_lifetimes)]
111#[allow(unused_qualifications)]
112#[rustfmt::skip]
113#[path = "./generated/layout.rs"]
114/// A serialized sequence of arrays, each with its buffers.
115///
116/// `layout.fbs`:
117/// ```flatbuffers
118#[doc = include_str!("../flatbuffers/vortex-layout/layout.fbs")]
119/// ```
120pub mod layout;
121
122#[cfg(feature = "ipc")]
123#[allow(clippy::all)]
124#[allow(clippy::derive_partial_eq_without_eq)]
125#[allow(clippy::many_single_char_names)]
126#[allow(clippy::unwrap_used)]
127#[allow(clippy::borrow_as_ptr)]
128#[allow(dead_code)]
129#[allow(non_snake_case)]
130#[allow(non_camel_case_types)]
131#[allow(unsafe_op_in_unsafe_fn)]
132#[allow(unused_imports)]
133#[allow(unused_lifetimes)]
134#[allow(unused_qualifications)]
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
154pub trait FlatBufferRoot {}
155
156pub trait ReadFlatBuffer: Sized {
157    type Source<'a>: Verifiable + Follow<'a>;
158    type Error: From<InvalidFlatbuffer>;
159
160    fn read_flatbuffer<'buf>(
161        fb: &<Self::Source<'buf> as Follow<'buf>>::Inner,
162    ) -> Result<Self, Self::Error>;
163
164    fn read_flatbuffer_bytes<'buf>(bytes: &'buf [u8]) -> Result<Self, Self::Error>
165    where
166        <Self as ReadFlatBuffer>::Source<'buf>: 'buf,
167    {
168        let fb = root::<Self::Source<'buf>>(bytes)?;
169        Self::read_flatbuffer(&fb)
170    }
171}
172
173pub trait WriteFlatBuffer {
174    type Target<'a>;
175
176    fn write_flatbuffer<'fb>(
177        &self,
178        fbb: &mut FlatBufferBuilder<'fb>,
179    ) -> WIPOffset<Self::Target<'fb>>;
180}
181
182pub trait WriteFlatBufferExt: WriteFlatBuffer + FlatBufferRoot {
183    /// Write the flatbuffer into a [`FlatBuffer`].
184    fn write_flatbuffer_bytes(&self) -> FlatBuffer;
185}
186
187impl<F: WriteFlatBuffer + FlatBufferRoot> WriteFlatBufferExt for F {
188    fn write_flatbuffer_bytes(&self) -> FlatBuffer {
189        let mut fbb = FlatBufferBuilder::new();
190        let root_offset = self.write_flatbuffer(&mut fbb);
191        fbb.finish_minimal(root_offset);
192        let (vec, start) = fbb.collapse();
193        let end = vec.len();
194        FlatBuffer::align_from(ByteBuffer::from(vec).slice(start..end))
195    }
196}