vortex_file/footer/
segment.rs1use std::ops::Range;
5
6use vortex_buffer::Alignment;
7use vortex_error::VortexError;
8use vortex_flatbuffers::footer as fb;
9
10#[derive(Clone, Copy, Debug)]
15pub struct SegmentSpec {
16 pub offset: u64,
18 pub length: u32,
20 pub alignment: Alignment,
22}
23
24impl SegmentSpec {
25 pub fn byte_range(&self) -> Range<u64> {
29 self.offset..self.offset + u64::from(self.length)
30 }
31}
32
33impl From<&SegmentSpec> for fb::SegmentSpec {
34 fn from(value: &SegmentSpec) -> Self {
35 fb::SegmentSpec::new(value.offset, value.length, value.alignment.exponent(), 0, 0)
36 }
37}
38
39impl TryFrom<&fb::SegmentSpec> for SegmentSpec {
40 type Error = VortexError;
41
42 fn try_from(value: &fb::SegmentSpec) -> Result<Self, Self::Error> {
43 Ok(Self {
44 offset: value.offset(),
45 length: value.length(),
46 alignment: Alignment::try_from_exponent(value.alignment_exponent())?,
49 })
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn rejects_out_of_range_alignment_exponent() {
59 let fb_spec = fb::SegmentSpec::new(0, 0, u8::MAX, 0, 0);
62 let err = SegmentSpec::try_from(&fb_spec).unwrap_err();
63 assert!(err.to_string().contains("too large"), "{err}");
64 }
65}