Skip to content

Commit

Permalink
Store unix_mode in a struct to make it optional
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcefrog committed Aug 26, 2023
1 parent 62c942d commit 98fd0fd
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 10 deletions.
7 changes: 6 additions & 1 deletion flatbuffers/index.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ table Addr {
len: uint64;
}

// In a struct so that it we can distinguish "not set" from 0o000.
struct UnixMode {
mode: uint16;
}

table Entry {
apath:string;
kind:Kind;
target:string; // only for kind == Symlink
mtime:int64;
mtime_nanos:uint32;
unix_mode:uint32 = 0xffffffff; // default = unset
unix_mode: UnixMode;
addrs: [Addr];
user: string;
group: string;
Expand Down
6 changes: 5 additions & 1 deletion src/fbs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ pub fn write_index(st: &StoredTree, mut out_file: File) -> Result<()> {
.target
.as_ref()
.map(|target| builder.create_string(target));
let unix_mode = entry
.unix_mode
.as_u32()
.map(|mode| gen::UnixMode::new(mode.try_into().expect("unix mode too large")));
gen::Entry::create(
&mut builder,
&gen::EntryArgs {
Expand All @@ -79,7 +83,7 @@ pub fn write_index(st: &StoredTree, mut out_file: File) -> Result<()> {
target,
mtime: entry.mtime,
mtime_nanos: entry.mtime_nanos,
unix_mode: entry.unix_mode.as_u32().unwrap_or(u32::MAX),
unix_mode: unix_mode.as_ref(),
user,
group,
},
Expand Down
108 changes: 100 additions & 8 deletions src/fbs/index_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,98 @@ impl<'a> flatbuffers::Verifiable for Kind {
}

impl flatbuffers::SimpleToVerifyInSlice for Kind {}
// struct UnixMode, aligned to 2
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq)]
pub struct UnixMode(pub [u8; 2]);
impl Default for UnixMode {
fn default() -> Self {
Self([0; 2])
}
}
impl core::fmt::Debug for UnixMode {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_struct("UnixMode")
.field("mode", &self.mode())
.finish()
}
}

impl flatbuffers::SimpleToVerifyInSlice for UnixMode {}
impl<'a> flatbuffers::Follow<'a> for UnixMode {
type Inner = &'a UnixMode;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
<&'a UnixMode>::follow(buf, loc)
}
}
impl<'a> flatbuffers::Follow<'a> for &'a UnixMode {
type Inner = &'a UnixMode;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
flatbuffers::follow_cast_ref::<UnixMode>(buf, loc)
}
}
impl<'b> flatbuffers::Push for UnixMode {
type Output = UnixMode;
#[inline]
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
let src = ::core::slice::from_raw_parts(self as *const UnixMode as *const u8, Self::size());
dst.copy_from_slice(src);
}
}

impl<'a> flatbuffers::Verifiable for UnixMode {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier, pos: usize
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.in_buffer::<Self>(pos)
}
}

impl<'a> UnixMode {
#[allow(clippy::too_many_arguments)]
pub fn new(
mode: u16,
) -> Self {
let mut s = Self([0; 2]);
s.set_mode(mode);
s
}

pub fn mode(&self) -> u16 {
let mut mem = core::mem::MaybeUninit::<<u16 as EndianScalar>::Scalar>::uninit();
// Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
EndianScalar::from_little_endian(unsafe {
core::ptr::copy_nonoverlapping(
self.0[0..].as_ptr(),
mem.as_mut_ptr() as *mut u8,
core::mem::size_of::<<u16 as EndianScalar>::Scalar>(),
);
mem.assume_init()
})
}

pub fn set_mode(&mut self, x: u16) {
let x_le = x.to_little_endian();
// Safety:
// Created from a valid Table for this object
// Which contains a valid value in this slot
unsafe {
core::ptr::copy_nonoverlapping(
&x_le as *const _ as *const u8,
self.0[0..].as_mut_ptr(),
core::mem::size_of::<<u16 as EndianScalar>::Scalar>(),
);
}
}

}

pub enum AddrOffset {}
#[derive(Copy, Clone, PartialEq)]

Expand Down Expand Up @@ -286,7 +378,7 @@ impl<'a> Entry<'a> {
if let Some(x) = args.group { builder.add_group(x); }
if let Some(x) = args.user { builder.add_user(x); }
if let Some(x) = args.addrs { builder.add_addrs(x); }
builder.add_unix_mode(args.unix_mode);
if let Some(x) = args.unix_mode { builder.add_unix_mode(x); }
builder.add_mtime_nanos(args.mtime_nanos);
if let Some(x) = args.target { builder.add_target(x); }
if let Some(x) = args.apath { builder.add_apath(x); }
Expand Down Expand Up @@ -331,11 +423,11 @@ impl<'a> Entry<'a> {
unsafe { self._tab.get::<u32>(Entry::VT_MTIME_NANOS, Some(0)).unwrap()}
}
#[inline]
pub fn unix_mode(&self) -> u32 {
pub fn unix_mode(&self) -> Option<&'a UnixMode> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<u32>(Entry::VT_UNIX_MODE, Some(4294967295)).unwrap()}
unsafe { self._tab.get::<UnixMode>(Entry::VT_UNIX_MODE, None)}
}
#[inline]
pub fn addrs(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Addr<'a>>>> {
Expand Down Expand Up @@ -372,7 +464,7 @@ impl flatbuffers::Verifiable for Entry<'_> {
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("target", Self::VT_TARGET, false)?
.visit_field::<i64>("mtime", Self::VT_MTIME, false)?
.visit_field::<u32>("mtime_nanos", Self::VT_MTIME_NANOS, false)?
.visit_field::<u32>("unix_mode", Self::VT_UNIX_MODE, false)?
.visit_field::<UnixMode>("unix_mode", Self::VT_UNIX_MODE, false)?
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Addr>>>>("addrs", Self::VT_ADDRS, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("user", Self::VT_USER, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("group", Self::VT_GROUP, false)?
Expand All @@ -386,7 +478,7 @@ pub struct EntryArgs<'a> {
pub target: Option<flatbuffers::WIPOffset<&'a str>>,
pub mtime: i64,
pub mtime_nanos: u32,
pub unix_mode: u32,
pub unix_mode: Option<&'a UnixMode>,
pub addrs: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Addr<'a>>>>>,
pub user: Option<flatbuffers::WIPOffset<&'a str>>,
pub group: Option<flatbuffers::WIPOffset<&'a str>>,
Expand All @@ -400,7 +492,7 @@ impl<'a> Default for EntryArgs<'a> {
target: None,
mtime: 0,
mtime_nanos: 0,
unix_mode: 4294967295,
unix_mode: None,
addrs: None,
user: None,
group: None,
Expand Down Expand Up @@ -434,8 +526,8 @@ impl<'a: 'b, 'b> EntryBuilder<'a, 'b> {
self.fbb_.push_slot::<u32>(Entry::VT_MTIME_NANOS, mtime_nanos, 0);
}
#[inline]
pub fn add_unix_mode(&mut self, unix_mode: u32) {
self.fbb_.push_slot::<u32>(Entry::VT_UNIX_MODE, unix_mode, 4294967295);
pub fn add_unix_mode(&mut self, unix_mode: &UnixMode) {
self.fbb_.push_slot_always::<&UnixMode>(Entry::VT_UNIX_MODE, unix_mode);
}
#[inline]
pub fn add_addrs(&mut self, addrs: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Addr<'b >>>>) {
Expand Down

0 comments on commit 98fd0fd

Please sign in to comment.