Files
flatbuffers/rust/reflection/src/struct.rs
Chan Wang 733e432bfd Rust full reflection (#8102)
* #Rust Create a crate for reflection

* #Rust Add a crate for reflection tests and helper to access schema

* #Rust Get root table of a buffer and access field with schema

* #Rust Add 'Struct' struct and corresponding getter

* #Rust Add functions of getting any table/struct field value as integer/float/string

* #Rust Add setters for scalar fields

* #Rust Add setter for string fields

* #Rust Add getter for Table/Vector fields

* #Rust Add buffer verification

* Add a 'SafeBuffer' struct which provides safe methods for reflection

It verifies buffer against schema during construction and provides all the unsafe getters in lib.rs in a safe way

---------

Co-authored-by: Derek Bailey <derekbailey@google.com>
2025-01-15 10:03:10 -08:00

62 lines
1.6 KiB
Rust

/*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use flatbuffers::Follow;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Struct<'a> {
buf: &'a [u8],
loc: usize,
}
impl<'a> Struct<'a> {
#[inline]
pub fn buf(&self) -> &'a [u8] {
self.buf
}
#[inline]
pub fn loc(&self) -> usize {
self.loc
}
/// # Safety
///
/// [buf] must contain a valid struct at [loc]
#[inline]
pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
Struct { buf, loc }
}
/// Retrieves the value at the provided [byte_loc]. No field in [Struct] is optional.
///
/// # Safety
///
/// The value of the corresponding slot must have type T
#[inline]
pub unsafe fn get<T: Follow<'a> + 'a>(&self, byte_loc: usize) -> T::Inner {
<T>::follow(self.buf, self.loc + byte_loc)
}
}
impl<'a> Follow<'a> for Struct<'a> {
type Inner = Struct<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Struct { buf, loc }
}
}