use crate::{ExtentDataRef, SharedDataRef};
use num_enum::{IntoPrimitive, TryFromPrimitive};
use static_assertions::{const_assert, const_assert_eq};
use strum::EnumIter;
use zerocopy::little_endian::U64 as U64LE;
use zerocopy_derive::*;
#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineRefHeader {
pub ref_type: ExtentInlineRefType,
pub offset: U64LE,
}
const_assert_eq!(core::mem::size_of::<ExtentInlineRefHeader>(), 9);
#[derive(Copy, Clone, TryFromBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineRefFull {
pub ref_type: ExtentInlineRefType,
pub tail: ExtentInlineRefTail,
}
const_assert_eq!(core::mem::size_of::<ExtentInlineRefFull>(), 29);
impl ExtentInlineRefFull {
pub fn offset(&self) -> Option<u64> {
match self.ref_type {
ExtentInlineRefType::TreeBlockRef | ExtentInlineRefType::SharedBlockRef => {
Some(unsafe { self.tail.offset.get() })
}
ExtentInlineRefType::SharedDataRef => {
Some(unsafe { self.tail.shared_data_tail.offset.get() })
}
_ => None,
}
}
pub fn extent_data_ref(&self) -> Option<ExtentDataRef> {
if self.ref_type == ExtentInlineRefType::ExtentDataRef {
Some(unsafe { self.tail.extent_data_ref })
} else {
None
}
}
pub fn shared_data_tail(&self) -> Option<ExtentInlineRefSharedDataTail> {
if self.ref_type == ExtentInlineRefType::SharedDataRef {
Some(unsafe { self.tail.shared_data_tail })
} else {
None
}
}
pub fn as_tree_block_ref(&self) -> Option<&ExtentInlineTreeBlockRef> {
const_assert!(
core::mem::size_of::<ExtentInlineRefFull>()
>= core::mem::size_of::<ExtentInlineTreeBlockRef>()
);
if self.ref_type == ExtentInlineRefType::TreeBlockRef {
Some(unsafe {
&*(self as *const ExtentInlineRefFull as *const ExtentInlineTreeBlockRef)
})
} else {
None
}
}
pub fn as_shared_block_ref(&self) -> Option<&ExtentInlineSharedBlockRef> {
const_assert!(
core::mem::size_of::<ExtentInlineRefFull>()
>= core::mem::size_of::<ExtentInlineSharedBlockRef>()
);
if self.ref_type == ExtentInlineRefType::SharedBlockRef {
Some(unsafe {
&*(self as *const ExtentInlineRefFull as *const ExtentInlineSharedBlockRef)
})
} else {
None
}
}
pub fn as_extent_data_ref(&self) -> Option<&ExtentInlineExtentDataRef> {
const_assert!(
core::mem::size_of::<ExtentInlineRefFull>()
>= core::mem::size_of::<ExtentInlineExtentDataRef>()
);
if self.ref_type == ExtentInlineRefType::ExtentDataRef {
Some(unsafe {
&*(self as *const ExtentInlineRefFull as *const ExtentInlineExtentDataRef)
})
} else {
None
}
}
pub fn as_shared_data_ref(&self) -> Option<&ExtentInlineSharedDataRef> {
const_assert!(
core::mem::size_of::<ExtentInlineRefFull>()
>= core::mem::size_of::<ExtentInlineSharedDataRef>()
);
if self.ref_type == ExtentInlineRefType::SharedDataRef {
Some(unsafe {
&*(self as *const ExtentInlineRefFull as *const ExtentInlineSharedDataRef)
})
} else {
None
}
}
}
#[derive(Copy, Clone, FromBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub union ExtentInlineRefTail {
pub offset: U64LE,
pub extent_data_ref: ExtentDataRef,
pub shared_data_tail: ExtentInlineRefSharedDataTail,
}
#[derive(Copy, Clone, Debug, Hash, FromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineRefSharedDataTail {
pub offset: U64LE,
pub shared_data_ref: SharedDataRef,
}
#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineTreeBlockRef {
ref_type: ExtentInlineTreeBlockRefType,
pub offset: U64LE,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum ExtentInlineTreeBlockRefType {
#[allow(dead_code)]
TreeBlockRef = ExtentInlineRefType::TreeBlockRef as u8,
}
const_assert_eq!(
core::mem::size_of::<ExtentInlineTreeBlockRefType>(),
core::mem::size_of::<ExtentInlineRefType>()
);
#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineSharedBlockRef {
ref_type: ExtentInlineSharedBlockRefType,
pub offset: U64LE,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(u8)]
#[allow(dead_code)]
enum ExtentInlineSharedBlockRefType {
SharedBlockRef = ExtentInlineRefType::SharedBlockRef as u8,
}
#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineExtentDataRef {
ref_type: ExtentInlineExtentDataRefType,
pub extent_data_ref: ExtentDataRef,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum ExtentInlineExtentDataRefType {
#[allow(dead_code)]
ExtentDataRef = ExtentInlineRefType::ExtentDataRef as u8,
}
const_assert_eq!(
core::mem::size_of::<ExtentInlineExtentDataRefType>(),
core::mem::size_of::<ExtentInlineRefType>()
);
#[derive(Copy, Clone, Debug, Hash, TryFromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(C, packed)]
pub struct ExtentInlineSharedDataRef {
ref_type: ExtentInlineSharedDataRefType,
pub shared_data_tail: ExtentInlineRefSharedDataTail,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum ExtentInlineSharedDataRefType {
#[allow(dead_code)]
SharedDataRef = ExtentInlineRefType::SharedDataRef as u8,
}
const_assert_eq!(
core::mem::size_of::<ExtentInlineSharedDataRefType>(),
core::mem::size_of::<ExtentInlineRefType>()
);
#[derive(
Copy,
Clone,
Debug,
Hash,
PartialEq,
EnumIter,
IntoPrimitive,
TryFromPrimitive,
TryFromBytes,
IntoBytes,
KnownLayout,
Immutable,
)]
#[repr(u8)]
pub enum ExtentInlineRefType {
TreeBlockRef = 176,
SharedBlockRef = 182,
ExtentDataRef = 178,
SharedDataRef = 184,
}