blob: d1d6483ae6718bef49a06a2fdb1990e50206e94a [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001/*
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
James Kuszmaul8e62b022022-03-22 09:33:25 -070017use core::marker::PhantomData;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070018
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.
James Kuszmaul8e62b022022-03-22 09:33:25 -070030pub trait Follow<'buf> {
Austin Schuhe89fa2d2019-08-14 20:24:23 -070031 type Inner;
James Kuszmaul8e62b022022-03-22 09:33:25 -070032 fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner;
Austin Schuhe89fa2d2019-08-14 20:24:23 -070033}
34
35/// FollowStart wraps a Follow impl in a struct type. This can make certain
36/// programming patterns more ergonomic.
Austin Schuh272c6132020-11-14 16:37:52 -080037#[derive(Debug, Default)]
Austin Schuhe89fa2d2019-08-14 20:24:23 -070038pub struct FollowStart<T>(PhantomData<T>);
39impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
40 #[inline]
41 pub fn new() -> Self {
42 Self { 0: PhantomData }
43 }
44 #[inline]
45 pub fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner {
46 T::follow(buf, loc)
47 }
48}
49impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
50 type Inner = T::Inner;
51 #[inline]
52 fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
53 T::follow(buf, loc)
54 }
55}