/rust/registry/src/index.crates.io-1949cf8c6b5b557f/flatbuffers-25.2.10/src/follow.rs
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2018 Google Inc. All rights reserved. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | use core::marker::PhantomData; |
18 | | |
19 | | /// Follow is a trait that allows us to access FlatBuffers in a declarative, |
20 | | /// type safe, and fast way. They compile down to almost no code (after |
21 | | /// optimizations). Conceptually, Follow lifts the offset-based access |
22 | | /// patterns of FlatBuffers data into the type system. This trait is used |
23 | | /// pervasively at read time, to access tables, vtables, vectors, strings, and |
24 | | /// all other data. At this time, Follow is not utilized much on the write |
25 | | /// path. |
26 | | /// |
27 | | /// Writing a new Follow implementation primarily involves deciding whether |
28 | | /// you want to return data (of the type Self::Inner) or do you want to |
29 | | /// continue traversing the FlatBuffer. |
30 | | pub trait Follow<'buf> { |
31 | | type Inner; |
32 | | /// # Safety |
33 | | /// |
34 | | /// `buf[loc..]` must contain a valid value of `Self` and anything it |
35 | | /// transitively refers to by offset must also be valid |
36 | | unsafe fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner; |
37 | | } |
38 | | |
39 | | /// FollowStart wraps a Follow impl in a struct type. This can make certain |
40 | | /// programming patterns more ergonomic. |
41 | | #[derive(Debug, Default)] |
42 | | pub struct FollowStart<T>(PhantomData<T>); |
43 | | impl<'a, T: Follow<'a> + 'a> FollowStart<T> { |
44 | | #[inline] |
45 | 0 | pub fn new() -> Self { |
46 | 0 | Self(PhantomData) |
47 | 0 | } |
48 | | |
49 | | /// # Safety |
50 | | /// |
51 | | /// `buf[loc..]` must contain a valid value of `T` |
52 | | #[inline] |
53 | 0 | pub unsafe fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner { |
54 | 0 | T::follow(buf, loc) |
55 | 0 | } |
56 | | } |
57 | | impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> { |
58 | | type Inner = T::Inner; |
59 | | #[inline] |
60 | 0 | unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { |
61 | 0 | T::follow(buf, loc) |
62 | 0 | } |
63 | | } |