diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 833c928fe..a2d9d6ece 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -47,7 +47,9 @@ use crate::io::{Buffer, Completion, ReadCompletion, SyncCompletion, WriteComplet use crate::storage::buffer_pool::BufferPool; use crate::storage::database::DatabaseStorage; use crate::storage::pager::Pager; -use crate::types::{ImmutableRecord, RawSlice, RefValue, SerialType, TextRef, TextSubtype}; +use crate::types::{ + ImmutableRecord, RawSlice, RefValue, SerialType, SerialTypeKind, TextRef, TextSubtype, +}; use crate::{File, Result}; use std::cell::RefCell; use std::mem::MaybeUninit; @@ -1117,16 +1119,16 @@ pub fn read_record(payload: &[u8], reuse_immutable: &mut ImmutableRecord) -> Res /// always. #[inline(always)] pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usize)> { - match serial_type { - SerialType::Null => Ok((RefValue::Null, 0)), - SerialType::I8 => { + match serial_type.kind() { + SerialTypeKind::Null => Ok((RefValue::Null, 0)), + SerialTypeKind::I8 => { if buf.is_empty() { crate::bail_corrupt_error!("Invalid UInt8 value"); } let val = buf[0] as i8; Ok((RefValue::Integer(val as i64), 1)) } - SerialType::I16 => { + SerialTypeKind::I16 => { if buf.len() < 2 { crate::bail_corrupt_error!("Invalid BEInt16 value"); } @@ -1135,7 +1137,7 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 2, )) } - SerialType::I24 => { + SerialTypeKind::I24 => { if buf.len() < 3 { crate::bail_corrupt_error!("Invalid BEInt24 value"); } @@ -1147,7 +1149,7 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 3, )) } - SerialType::I32 => { + SerialTypeKind::I32 => { if buf.len() < 4 { crate::bail_corrupt_error!("Invalid BEInt32 value"); } @@ -1156,7 +1158,7 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 4, )) } - SerialType::I48 => { + SerialTypeKind::I48 => { if buf.len() < 6 { crate::bail_corrupt_error!("Invalid BEInt48 value"); } @@ -1175,7 +1177,7 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 6, )) } - SerialType::I64 => { + SerialTypeKind::I64 => { if buf.len() < 8 { crate::bail_corrupt_error!("Invalid BEInt64 value"); } @@ -1186,7 +1188,7 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 8, )) } - SerialType::F64 => { + SerialTypeKind::F64 => { if buf.len() < 8 { crate::bail_corrupt_error!("Invalid BEFloat64 value"); } @@ -1197,9 +1199,10 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz 8, )) } - SerialType::ConstInt0 => Ok((RefValue::Integer(0), 0)), - SerialType::ConstInt1 => Ok((RefValue::Integer(1), 0)), - SerialType::Blob { content_size } => { + SerialTypeKind::ConstInt0 => Ok((RefValue::Integer(0), 0)), + SerialTypeKind::ConstInt1 => Ok((RefValue::Integer(1), 0)), + SerialTypeKind::Blob => { + let content_size = serial_type.size(); if buf.len() < content_size { crate::bail_corrupt_error!("Invalid Blob value"); } @@ -1211,7 +1214,8 @@ pub fn read_value(buf: &[u8], serial_type: SerialType) -> Result<(RefValue, usiz Ok((RefValue::Blob(slice), content_size)) } } - SerialType::Text { content_size } => { + SerialTypeKind::Text => { + let content_size = serial_type.size(); if buf.len() < content_size { crate::bail_corrupt_error!( "Invalid String value, length {} < expected length {}", @@ -1567,32 +1571,32 @@ mod tests { use rstest::rstest; #[rstest] - #[case(&[], SerialType::Null, OwnedValue::Null)] - #[case(&[255], SerialType::I8, OwnedValue::Integer(-1))] - #[case(&[0x12, 0x34], SerialType::I16, OwnedValue::Integer(0x1234))] - #[case(&[0xFE], SerialType::I8, OwnedValue::Integer(-2))] - #[case(&[0x12, 0x34, 0x56], SerialType::I24, OwnedValue::Integer(0x123456))] - #[case(&[0x12, 0x34, 0x56, 0x78], SerialType::I32, OwnedValue::Integer(0x12345678))] - #[case(&[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC], SerialType::I48, OwnedValue::Integer(0x123456789ABC))] - #[case(&[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF], SerialType::I64, OwnedValue::Integer(0x123456789ABCDEFF))] - #[case(&[0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18], SerialType::F64, OwnedValue::Float(std::f64::consts::PI))] - #[case(&[1, 2], SerialType::ConstInt0, OwnedValue::Integer(0))] - #[case(&[65, 66], SerialType::ConstInt1, OwnedValue::Integer(1))] - #[case(&[1, 2, 3], SerialType::Blob { content_size: 3 }, OwnedValue::Blob(vec![1, 2, 3].into()))] - #[case(&[], SerialType::Blob { content_size: 0 }, OwnedValue::Blob(vec![].into()))] // empty blob - #[case(&[65, 66, 67], SerialType::Text { content_size: 3 }, OwnedValue::build_text("ABC"))] - #[case(&[0x80], SerialType::I8, OwnedValue::Integer(-128))] - #[case(&[0x80, 0], SerialType::I16, OwnedValue::Integer(-32768))] - #[case(&[0x80, 0, 0], SerialType::I24, OwnedValue::Integer(-8388608))] - #[case(&[0x80, 0, 0, 0], SerialType::I32, OwnedValue::Integer(-2147483648))] - #[case(&[0x80, 0, 0, 0, 0, 0], SerialType::I48, OwnedValue::Integer(-140737488355328))] - #[case(&[0x80, 0, 0, 0, 0, 0, 0, 0], SerialType::I64, OwnedValue::Integer(-9223372036854775808))] - #[case(&[0x7f], SerialType::I8, OwnedValue::Integer(127))] - #[case(&[0x7f, 0xff], SerialType::I16, OwnedValue::Integer(32767))] - #[case(&[0x7f, 0xff, 0xff], SerialType::I24, OwnedValue::Integer(8388607))] - #[case(&[0x7f, 0xff, 0xff, 0xff], SerialType::I32, OwnedValue::Integer(2147483647))] - #[case(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff], SerialType::I48, OwnedValue::Integer(140737488355327))] - #[case(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], SerialType::I64, OwnedValue::Integer(9223372036854775807))] + #[case(&[], SerialType::null(), OwnedValue::Null)] + #[case(&[255], SerialType::i8(), OwnedValue::Integer(-1))] + #[case(&[0x12, 0x34], SerialType::i16(), OwnedValue::Integer(0x1234))] + #[case(&[0xFE], SerialType::i8(), OwnedValue::Integer(-2))] + #[case(&[0x12, 0x34, 0x56], SerialType::i24(), OwnedValue::Integer(0x123456))] + #[case(&[0x12, 0x34, 0x56, 0x78], SerialType::i32(), OwnedValue::Integer(0x12345678))] + #[case(&[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC], SerialType::i48(), OwnedValue::Integer(0x123456789ABC))] + #[case(&[0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF], SerialType::i64(), OwnedValue::Integer(0x123456789ABCDEFF))] + #[case(&[0x40, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18], SerialType::f64(), OwnedValue::Float(std::f64::consts::PI))] + #[case(&[1, 2], SerialType::const_int0(), OwnedValue::Integer(0))] + #[case(&[65, 66], SerialType::const_int1(), OwnedValue::Integer(1))] + #[case(&[1, 2, 3], SerialType::blob(3), OwnedValue::Blob(vec![1, 2, 3].into()))] + #[case(&[], SerialType::blob(0), OwnedValue::Blob(vec![].into()))] // empty blob + #[case(&[65, 66, 67], SerialType::text(3), OwnedValue::build_text("ABC"))] + #[case(&[0x80], SerialType::i8(), OwnedValue::Integer(-128))] + #[case(&[0x80, 0], SerialType::i16(), OwnedValue::Integer(-32768))] + #[case(&[0x80, 0, 0], SerialType::i24(), OwnedValue::Integer(-8388608))] + #[case(&[0x80, 0, 0, 0], SerialType::i32(), OwnedValue::Integer(-2147483648))] + #[case(&[0x80, 0, 0, 0, 0, 0], SerialType::i48(), OwnedValue::Integer(-140737488355328))] + #[case(&[0x80, 0, 0, 0, 0, 0, 0, 0], SerialType::i64(), OwnedValue::Integer(-9223372036854775808))] + #[case(&[0x7f], SerialType::i8(), OwnedValue::Integer(127))] + #[case(&[0x7f, 0xff], SerialType::i16(), OwnedValue::Integer(32767))] + #[case(&[0x7f, 0xff, 0xff], SerialType::i24(), OwnedValue::Integer(8388607))] + #[case(&[0x7f, 0xff, 0xff, 0xff], SerialType::i32(), OwnedValue::Integer(2147483647))] + #[case(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff], SerialType::i48(), OwnedValue::Integer(140737488355327))] + #[case(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], SerialType::i64(), OwnedValue::Integer(9223372036854775807))] fn test_read_value( #[case] buf: &[u8], #[case] serial_type: SerialType, @@ -1606,45 +1610,45 @@ mod tests { fn test_serial_type_helpers() { assert_eq!( TryInto::::try_into(12u64).unwrap(), - SerialType::Blob { content_size: 0 } + SerialType::blob(0) ); assert_eq!( TryInto::::try_into(14u64).unwrap(), - SerialType::Blob { content_size: 1 } + SerialType::blob(1) ); assert_eq!( TryInto::::try_into(13u64).unwrap(), - SerialType::Text { content_size: 0 } + SerialType::text(0) ); assert_eq!( TryInto::::try_into(15u64).unwrap(), - SerialType::Text { content_size: 1 } + SerialType::text(1) ); assert_eq!( TryInto::::try_into(16u64).unwrap(), - SerialType::Blob { content_size: 2 } + SerialType::blob(2) ); assert_eq!( TryInto::::try_into(17u64).unwrap(), - SerialType::Text { content_size: 2 } + SerialType::text(2) ); } #[rstest] - #[case(0, SerialType::Null)] - #[case(1, SerialType::I8)] - #[case(2, SerialType::I16)] - #[case(3, SerialType::I24)] - #[case(4, SerialType::I32)] - #[case(5, SerialType::I48)] - #[case(6, SerialType::I64)] - #[case(7, SerialType::F64)] - #[case(8, SerialType::ConstInt0)] - #[case(9, SerialType::ConstInt1)] - #[case(12, SerialType::Blob { content_size: 0 })] - #[case(13, SerialType::Text { content_size: 0 })] - #[case(14, SerialType::Blob { content_size: 1 })] - #[case(15, SerialType::Text { content_size: 1 })] + #[case(0, SerialType::null())] + #[case(1, SerialType::i8())] + #[case(2, SerialType::i16())] + #[case(3, SerialType::i24())] + #[case(4, SerialType::i32())] + #[case(5, SerialType::i48())] + #[case(6, SerialType::i64())] + #[case(7, SerialType::f64())] + #[case(8, SerialType::const_int0())] + #[case(9, SerialType::const_int1())] + #[case(12, SerialType::blob(0))] + #[case(13, SerialType::text(0))] + #[case(14, SerialType::blob(1))] + #[case(15, SerialType::text(1))] fn test_parse_serial_type(#[case] input: u64, #[case] expected: SerialType) { let result = SerialType::try_from(input).unwrap(); assert_eq!(result, expected); diff --git a/core/types.rs b/core/types.rs index 4173324f8..b2a7a053b 100644 --- a/core/types.rs +++ b/core/types.rs @@ -171,13 +171,13 @@ impl OwnedValue { OwnedValue::Null => {} OwnedValue::Integer(i) => { let serial_type = SerialType::from(self); - match serial_type { - SerialType::I8 => out.extend_from_slice(&(*i as i8).to_be_bytes()), - SerialType::I16 => out.extend_from_slice(&(*i as i16).to_be_bytes()), - SerialType::I24 => out.extend_from_slice(&(*i as i32).to_be_bytes()[1..]), // remove most significant byte - SerialType::I32 => out.extend_from_slice(&(*i as i32).to_be_bytes()), - SerialType::I48 => out.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes - SerialType::I64 => out.extend_from_slice(&i.to_be_bytes()), + match serial_type.kind() { + SerialTypeKind::I8 => out.extend_from_slice(&(*i as i8).to_be_bytes()), + SerialTypeKind::I16 => out.extend_from_slice(&(*i as i16).to_be_bytes()), + SerialTypeKind::I24 => out.extend_from_slice(&(*i as i32).to_be_bytes()[1..]), // remove most significant byte + SerialTypeKind::I32 => out.extend_from_slice(&(*i as i32).to_be_bytes()), + SerialTypeKind::I48 => out.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes + SerialTypeKind::I64 => out.extend_from_slice(&i.to_be_bytes()), _ => unreachable!(), } } @@ -786,18 +786,7 @@ impl ImmutableRecord { let n = write_varint(&mut serial_type_buf[0..], serial_type.into()); serials.push((serial_type_buf, n)); - let value_size = match serial_type { - SerialType::Null | SerialType::ConstInt0 | SerialType::ConstInt1 => 0, - SerialType::I8 => 1, - SerialType::I16 => 2, - SerialType::I24 => 3, - SerialType::I32 => 4, - SerialType::I48 => 6, - SerialType::I64 => 8, - SerialType::F64 => 8, - SerialType::Text { content_size } => content_size, - SerialType::Blob { content_size } => content_size, - }; + let value_size = serial_type.size(); size_header += n; size_values += value_size; @@ -844,16 +833,16 @@ impl ImmutableRecord { OwnedValue::Integer(i) => { values.push(RefValue::Integer(*i)); let serial_type = SerialType::from(value); - match serial_type { - SerialType::ConstInt0 | SerialType::ConstInt1 => {} - SerialType::I8 => writer.extend_from_slice(&(*i as i8).to_be_bytes()), - SerialType::I16 => writer.extend_from_slice(&(*i as i16).to_be_bytes()), - SerialType::I24 => { + match serial_type.kind() { + SerialTypeKind::ConstInt0 | SerialTypeKind::ConstInt1 => {} + SerialTypeKind::I8 => writer.extend_from_slice(&(*i as i8).to_be_bytes()), + SerialTypeKind::I16 => writer.extend_from_slice(&(*i as i16).to_be_bytes()), + SerialTypeKind::I24 => { writer.extend_from_slice(&(*i as i32).to_be_bytes()[1..]) } // remove most significant byte - SerialType::I32 => writer.extend_from_slice(&(*i as i32).to_be_bytes()), - SerialType::I48 => writer.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes - SerialType::I64 => writer.extend_from_slice(&i.to_be_bytes()), + SerialTypeKind::I32 => writer.extend_from_slice(&(*i as i32).to_be_bytes()), + SerialTypeKind::I48 => writer.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes + SerialTypeKind::I64 => writer.extend_from_slice(&i.to_be_bytes()), other => panic!("Serial type is not an integer: {:?}", other), } } @@ -1114,7 +1103,11 @@ const I48_HIGH: i64 = 140737488355327; /// Sqlite Serial Types /// https://www.sqlite.org/fileformat.html#record_format #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum SerialType { +#[repr(transparent)] +pub struct SerialType(u64); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum SerialTypeKind { Null, I8, I16, @@ -1125,8 +1118,8 @@ pub enum SerialType { F64, ConstInt0, ConstInt1, - Text { content_size: usize }, - Blob { content_size: usize }, + Text, + Blob, } impl SerialType { @@ -1134,81 +1127,143 @@ impl SerialType { pub fn u64_is_valid_serial_type(n: u64) -> bool { n != 10 && n != 11 } + + const NULL: Self = Self(0); + const I8: Self = Self(1); + const I16: Self = Self(2); + const I24: Self = Self(3); + const I32: Self = Self(4); + const I48: Self = Self(5); + const I64: Self = Self(6); + const F64: Self = Self(7); + const CONST_INT0: Self = Self(8); + const CONST_INT1: Self = Self(9); + + pub fn null() -> Self { + Self::NULL + } + + pub fn i8() -> Self { + Self::I8 + } + + pub fn i16() -> Self { + Self::I16 + } + + pub fn i24() -> Self { + Self::I24 + } + + pub fn i32() -> Self { + Self::I32 + } + + pub fn i48() -> Self { + Self::I48 + } + + pub fn i64() -> Self { + Self::I64 + } + + pub fn f64() -> Self { + Self::F64 + } + + pub fn const_int0() -> Self { + Self::CONST_INT0 + } + + pub fn const_int1() -> Self { + Self::CONST_INT1 + } + + pub fn blob(size: u64) -> Self { + Self(12 + size * 2) + } + + pub fn text(size: u64) -> Self { + Self(13 + size * 2) + } + + pub fn kind(&self) -> SerialTypeKind { + match self.0 { + 0 => SerialTypeKind::Null, + 1 => SerialTypeKind::I8, + 2 => SerialTypeKind::I16, + 3 => SerialTypeKind::I24, + 4 => SerialTypeKind::I32, + 5 => SerialTypeKind::I48, + 6 => SerialTypeKind::I64, + 7 => SerialTypeKind::F64, + 8 => SerialTypeKind::ConstInt0, + 9 => SerialTypeKind::ConstInt1, + n if n >= 12 => match n % 2 { + 0 => SerialTypeKind::Blob, + 1 => SerialTypeKind::Text, + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + + pub fn size(&self) -> usize { + match self.kind() { + SerialTypeKind::Null => 0, + SerialTypeKind::I8 => 1, + SerialTypeKind::I16 => 2, + SerialTypeKind::I24 => 3, + SerialTypeKind::I32 => 4, + SerialTypeKind::I48 => 6, + SerialTypeKind::I64 => 8, + SerialTypeKind::F64 => 8, + SerialTypeKind::ConstInt0 => 0, + SerialTypeKind::ConstInt1 => 0, + SerialTypeKind::Text => (self.0 as usize - 13) / 2, + SerialTypeKind::Blob => (self.0 as usize - 12) / 2, + } + } } impl From<&OwnedValue> for SerialType { fn from(value: &OwnedValue) -> Self { match value { - OwnedValue::Null => SerialType::Null, + OwnedValue::Null => SerialType::null(), OwnedValue::Integer(i) => match i { - 0 => SerialType::ConstInt0, - 1 => SerialType::ConstInt1, - i if *i >= I8_LOW && *i <= I8_HIGH => SerialType::I8, - i if *i >= I16_LOW && *i <= I16_HIGH => SerialType::I16, - i if *i >= I24_LOW && *i <= I24_HIGH => SerialType::I24, - i if *i >= I32_LOW && *i <= I32_HIGH => SerialType::I32, - i if *i >= I48_LOW && *i <= I48_HIGH => SerialType::I48, - _ => SerialType::I64, - }, - OwnedValue::Float(_) => SerialType::F64, - OwnedValue::Text(t) => SerialType::Text { - content_size: t.value.len(), - }, - OwnedValue::Blob(b) => SerialType::Blob { - content_size: b.len(), + 0 => SerialType::const_int0(), + 1 => SerialType::const_int1(), + i if *i >= I8_LOW && *i <= I8_HIGH => SerialType::i8(), + i if *i >= I16_LOW && *i <= I16_HIGH => SerialType::i16(), + i if *i >= I24_LOW && *i <= I24_HIGH => SerialType::i24(), + i if *i >= I32_LOW && *i <= I32_HIGH => SerialType::i32(), + i if *i >= I48_LOW && *i <= I48_HIGH => SerialType::i48(), + _ => SerialType::i64(), }, + OwnedValue::Float(_) => SerialType::f64(), + OwnedValue::Text(t) => SerialType::text(t.value.len() as u64), + OwnedValue::Blob(b) => SerialType::blob(b.len() as u64), } } } impl From for u64 { fn from(serial_type: SerialType) -> Self { - match serial_type { - SerialType::Null => 0, - SerialType::I8 => 1, - SerialType::I16 => 2, - SerialType::I24 => 3, - SerialType::I32 => 4, - SerialType::I48 => 5, - SerialType::I64 => 6, - SerialType::F64 => 7, - SerialType::ConstInt0 => 8, - SerialType::ConstInt1 => 9, - SerialType::Text { content_size } => (content_size * 2 + 13) as u64, - SerialType::Blob { content_size } => (content_size * 2 + 12) as u64, - } + serial_type.0 } } impl TryFrom for SerialType { type Error = LimboError; - fn try_from(serial_type: u64) -> Result { - match serial_type { - 0 => Ok(SerialType::Null), - 1 => Ok(SerialType::I8), - 2 => Ok(SerialType::I16), - 3 => Ok(SerialType::I24), - 4 => Ok(SerialType::I32), - 5 => Ok(SerialType::I48), - 6 => Ok(SerialType::I64), - 7 => Ok(SerialType::F64), - 8 => Ok(SerialType::ConstInt0), - 9 => Ok(SerialType::ConstInt1), - n if n >= 12 => match n % 2 { - 0 => Ok(SerialType::Blob { - content_size: (n as usize - 12) / 2, - }), - 1 => Ok(SerialType::Text { - content_size: (n as usize - 13) / 2, - }), - _ => unreachable!(), - }, - _ => Err(LimboError::Corrupt(format!( + fn try_from(uint: u64) -> Result { + if uint == 10 || uint == 11 { + return Err(LimboError::Corrupt(format!( "Invalid serial type: {}", - serial_type - ))), + uint + ))); } + Ok(SerialType(uint)) } } @@ -1236,13 +1291,15 @@ impl Record { OwnedValue::Null => {} OwnedValue::Integer(i) => { let serial_type = SerialType::from(value); - match serial_type { - SerialType::I8 => buf.extend_from_slice(&(*i as i8).to_be_bytes()), - SerialType::I16 => buf.extend_from_slice(&(*i as i16).to_be_bytes()), - SerialType::I24 => buf.extend_from_slice(&(*i as i32).to_be_bytes()[1..]), // remove most significant byte - SerialType::I32 => buf.extend_from_slice(&(*i as i32).to_be_bytes()), - SerialType::I48 => buf.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes - SerialType::I64 => buf.extend_from_slice(&i.to_be_bytes()), + match serial_type.kind() { + SerialTypeKind::I8 => buf.extend_from_slice(&(*i as i8).to_be_bytes()), + SerialTypeKind::I16 => buf.extend_from_slice(&(*i as i16).to_be_bytes()), + SerialTypeKind::I24 => { + buf.extend_from_slice(&(*i as i32).to_be_bytes()[1..]) + } // remove most significant byte + SerialTypeKind::I32 => buf.extend_from_slice(&(*i as i32).to_be_bytes()), + SerialTypeKind::I48 => buf.extend_from_slice(&i.to_be_bytes()[2..]), // remove 2 most significant bytes + SerialTypeKind::I64 => buf.extend_from_slice(&i.to_be_bytes()), _ => unreachable!(), } } @@ -1397,7 +1454,7 @@ mod tests { // First byte should be header size assert_eq!(header[0], header_length as u8); // Second byte should be serial type for NULL - assert_eq!(header[1] as u64, u64::from(SerialType::Null)); + assert_eq!(header[1] as u64, u64::from(SerialType::null())); // Check that the buffer is empty after the header assert_eq!(buf.len(), header_length); } @@ -1421,12 +1478,12 @@ mod tests { assert_eq!(header[0], header_length as u8); // Header should be larger than number of values // Check that correct serial types were chosen - assert_eq!(header[1] as u64, u64::from(SerialType::I8)); - assert_eq!(header[2] as u64, u64::from(SerialType::I16)); - assert_eq!(header[3] as u64, u64::from(SerialType::I24)); - assert_eq!(header[4] as u64, u64::from(SerialType::I32)); - assert_eq!(header[5] as u64, u64::from(SerialType::I48)); - assert_eq!(header[6] as u64, u64::from(SerialType::I64)); + assert_eq!(header[1] as u64, u64::from(SerialType::i8())); + assert_eq!(header[2] as u64, u64::from(SerialType::i16())); + assert_eq!(header[3] as u64, u64::from(SerialType::i24())); + assert_eq!(header[4] as u64, u64::from(SerialType::i32())); + assert_eq!(header[5] as u64, u64::from(SerialType::i48())); + assert_eq!(header[6] as u64, u64::from(SerialType::i64())); // test that the bytes after the header can be interpreted as the correct values let mut cur_offset = header_length; @@ -1489,7 +1546,7 @@ mod tests { // First byte should be header size assert_eq!(header[0], header_length as u8); // Second byte should be serial type for FLOAT - assert_eq!(header[1] as u64, u64::from(SerialType::F64)); + assert_eq!(header[1] as u64, u64::from(SerialType::f64())); // Check that the bytes after the header can be interpreted as the float let float_bytes = &buf[header_length..header_length + size_of::()]; let float = f64::from_be_bytes(float_bytes.try_into().unwrap()); @@ -1553,11 +1610,11 @@ mod tests { // First byte should be header size assert_eq!(header[0], header_length as u8); // Second byte should be serial type for NULL - assert_eq!(header[1] as u64, u64::from(SerialType::Null)); + assert_eq!(header[1] as u64, u64::from(SerialType::null())); // Third byte should be serial type for I8 - assert_eq!(header[2] as u64, u64::from(SerialType::I8)); + assert_eq!(header[2] as u64, u64::from(SerialType::i8())); // Fourth byte should be serial type for F64 - assert_eq!(header[3] as u64, u64::from(SerialType::F64)); + assert_eq!(header[3] as u64, u64::from(SerialType::f64())); // Fifth byte should be serial type for TEXT, which is (len * 2 + 13) assert_eq!(header[4] as u64, (4 * 2 + 13) as u64);