|
|
@ -13,7 +13,7 @@ use super::wrappers::Str; |
|
|
|
|
|
|
|
|
|
|
|
/// The error type for `Cursor` and `CursorMut`.
|
|
|
|
/// The error type for `Cursor` and `CursorMut`.
|
|
|
|
#[derive(Error, Debug, PartialEq, Eq)] |
|
|
|
#[derive(Error, Debug, PartialEq, Eq)] |
|
|
|
pub enum Error { |
|
|
|
pub enum CursorError { |
|
|
|
/// Invalid number.
|
|
|
|
/// Invalid number.
|
|
|
|
#[error("Invalid number")] |
|
|
|
#[error("Invalid number")] |
|
|
|
InvalidNumber, |
|
|
|
InvalidNumber, |
|
|
@ -43,53 +43,55 @@ pub enum Error { |
|
|
|
UnexpectedEnd, |
|
|
|
UnexpectedEnd, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub type Result<T, E = CursorError> = std::result::Result<T, E>; |
|
|
|
|
|
|
|
|
|
|
|
pub trait GetKeyValue<'a>: Sized { |
|
|
|
pub trait GetKeyValue<'a>: Sized { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error>; |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self>; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for &'a [u8] { |
|
|
|
impl<'a> GetKeyValue<'a> for &'a [u8] { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
cur.get_key_value_raw() |
|
|
|
cur.get_key_value_raw() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for Str<&'a [u8]> { |
|
|
|
impl<'a> GetKeyValue<'a> for Str<&'a [u8]> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
cur.get_key_value_raw().map(Str) |
|
|
|
cur.get_key_value_raw().map(Str) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for &'a str { |
|
|
|
impl<'a> GetKeyValue<'a> for &'a str { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
str::from_utf8(raw).map_err(|_| Error::InvalidString) |
|
|
|
str::from_utf8(raw).map_err(|_| CursorError::InvalidString) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for Box<str> { |
|
|
|
impl<'a> GetKeyValue<'a> for Box<str> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
str::from_utf8(raw) |
|
|
|
str::from_utf8(raw) |
|
|
|
.map(|s| s.to_owned().into_boxed_str()) |
|
|
|
.map(|s| s.to_owned().into_boxed_str()) |
|
|
|
.map_err(|_| Error::InvalidString) |
|
|
|
.map_err(|_| CursorError::InvalidString) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for String { |
|
|
|
impl<'a> GetKeyValue<'a> for String { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
let raw = cur.get_key_value_raw()?; |
|
|
|
str::from_utf8(raw) |
|
|
|
str::from_utf8(raw) |
|
|
|
.map(|s| s.to_owned()) |
|
|
|
.map(|s| s.to_owned()) |
|
|
|
.map_err(|_| Error::InvalidString) |
|
|
|
.map_err(|_| CursorError::InvalidString) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GetKeyValue<'a> for bool { |
|
|
|
impl<'a> GetKeyValue<'a> for bool { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
match cur.get_key_value_raw()? { |
|
|
|
match cur.get_key_value_raw()? { |
|
|
|
b"0" => Ok(false), |
|
|
|
b"0" => Ok(false), |
|
|
|
b"1" => Ok(true), |
|
|
|
b"1" => Ok(true), |
|
|
|
_ => Err(Error::InvalidBool), |
|
|
|
_ => Err(CursorError::InvalidBool), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -97,11 +99,11 @@ impl<'a> GetKeyValue<'a> for bool { |
|
|
|
macro_rules! impl_get_value { |
|
|
|
macro_rules! impl_get_value { |
|
|
|
($($t:ty),+ $(,)?) => { |
|
|
|
($($t:ty),+ $(,)?) => { |
|
|
|
$(impl<'a> GetKeyValue<'a> for $t { |
|
|
|
$(impl<'a> GetKeyValue<'a> for $t { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self, Error> { |
|
|
|
fn get_key_value(cur: &mut Cursor<'a>) -> Result<Self> { |
|
|
|
let s = cur.get_key_value::<&str>()?; |
|
|
|
let s = cur.get_key_value::<&str>()?; |
|
|
|
// HACK: special case for one asshole
|
|
|
|
// HACK: special case for one asshole
|
|
|
|
let (_, s) = color::trim_start_color(s); |
|
|
|
let (_, s) = color::trim_start_color(s); |
|
|
|
s.parse().map_err(|_| Error::InvalidNumber) |
|
|
|
s.parse().map_err(|_| CursorError::InvalidNumber) |
|
|
|
} |
|
|
|
} |
|
|
|
})+ |
|
|
|
})+ |
|
|
|
}; |
|
|
|
}; |
|
|
@ -129,7 +131,7 @@ pub struct Cursor<'a> { |
|
|
|
macro_rules! impl_get { |
|
|
|
macro_rules! impl_get { |
|
|
|
($($n:ident: $t:ty = $f:ident),+ $(,)?) => ( |
|
|
|
($($n:ident: $t:ty = $f:ident),+ $(,)?) => ( |
|
|
|
$(#[inline] |
|
|
|
$(#[inline] |
|
|
|
pub fn $n(&mut self) -> Result<$t, Error> { |
|
|
|
pub fn $n(&mut self) -> Result<$t> { |
|
|
|
const N: usize = mem::size_of::<$t>(); |
|
|
|
const N: usize = mem::size_of::<$t>(); |
|
|
|
self.get_array::<N>().map(<$t>::$f) |
|
|
|
self.get_array::<N>().map(<$t>::$f) |
|
|
|
})+ |
|
|
|
})+ |
|
|
@ -159,21 +161,21 @@ impl<'a> Cursor<'a> { |
|
|
|
self.remaining() != 0 |
|
|
|
self.remaining() != 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_bytes(&mut self, count: usize) -> Result<&'a [u8], Error> { |
|
|
|
pub fn get_bytes(&mut self, count: usize) -> Result<&'a [u8]> { |
|
|
|
if count <= self.remaining() { |
|
|
|
if count <= self.remaining() { |
|
|
|
let (head, tail) = self.buffer.split_at(count); |
|
|
|
let (head, tail) = self.buffer.split_at(count); |
|
|
|
self.buffer = tail; |
|
|
|
self.buffer = tail; |
|
|
|
Ok(head) |
|
|
|
Ok(head) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Err(Error::UnexpectedEnd) |
|
|
|
Err(CursorError::UnexpectedEnd) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn advance(&mut self, count: usize) -> Result<(), Error> { |
|
|
|
pub fn advance(&mut self, count: usize) -> Result<()> { |
|
|
|
self.get_bytes(count).map(|_| ()) |
|
|
|
self.get_bytes(count).map(|_| ()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_array<const N: usize>(&mut self) -> Result<[u8; N], Error> { |
|
|
|
pub fn get_array<const N: usize>(&mut self) -> Result<[u8; N]> { |
|
|
|
self.get_bytes(N).map(|s| { |
|
|
|
self.get_bytes(N).map(|s| { |
|
|
|
let mut array = [0; N]; |
|
|
|
let mut array = [0; N]; |
|
|
|
array.copy_from_slice(s); |
|
|
|
array.copy_from_slice(s); |
|
|
@ -181,37 +183,37 @@ impl<'a> Cursor<'a> { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_str(&mut self, n: usize) -> Result<&'a str, Error> { |
|
|
|
pub fn get_str(&mut self, n: usize) -> Result<&'a str> { |
|
|
|
let mut cur = *self; |
|
|
|
let mut cur = *self; |
|
|
|
let s = cur |
|
|
|
let s = cur |
|
|
|
.get_bytes(n) |
|
|
|
.get_bytes(n) |
|
|
|
.and_then(|s| str::from_utf8(s).map_err(|_| Error::InvalidString))?; |
|
|
|
.and_then(|s| str::from_utf8(s).map_err(|_| CursorError::InvalidString))?; |
|
|
|
*self = cur; |
|
|
|
*self = cur; |
|
|
|
Ok(s) |
|
|
|
Ok(s) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_cstr(&mut self) -> Result<Str<&'a [u8]>, Error> { |
|
|
|
pub fn get_cstr(&mut self) -> Result<Str<&'a [u8]>> { |
|
|
|
let pos = self |
|
|
|
let pos = self |
|
|
|
.buffer |
|
|
|
.buffer |
|
|
|
.iter() |
|
|
|
.iter() |
|
|
|
.position(|&c| c == b'\0') |
|
|
|
.position(|&c| c == b'\0') |
|
|
|
.ok_or(Error::UnexpectedEnd)?; |
|
|
|
.ok_or(CursorError::UnexpectedEnd)?; |
|
|
|
let (head, tail) = self.buffer.split_at(pos); |
|
|
|
let (head, tail) = self.buffer.split_at(pos); |
|
|
|
self.buffer = &tail[1..]; |
|
|
|
self.buffer = &tail[1..]; |
|
|
|
Ok(Str(&head[..pos])) |
|
|
|
Ok(Str(&head[..pos])) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_cstr_as_str(&mut self) -> Result<&'a str, Error> { |
|
|
|
pub fn get_cstr_as_str(&mut self) -> Result<&'a str> { |
|
|
|
str::from_utf8(&self.get_cstr()?).map_err(|_| Error::InvalidString) |
|
|
|
str::from_utf8(&self.get_cstr()?).map_err(|_| CursorError::InvalidString) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[inline(always)] |
|
|
|
#[inline(always)] |
|
|
|
pub fn get_u8(&mut self) -> Result<u8, Error> { |
|
|
|
pub fn get_u8(&mut self) -> Result<u8> { |
|
|
|
self.get_array::<1>().map(|s| s[0]) |
|
|
|
self.get_array::<1>().map(|s| s[0]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[inline(always)] |
|
|
|
#[inline(always)] |
|
|
|
pub fn get_i8(&mut self) -> Result<i8, Error> { |
|
|
|
pub fn get_i8(&mut self) -> Result<i8> { |
|
|
|
self.get_array::<1>().map(|s| s[0] as i8) |
|
|
|
self.get_array::<1>().map(|s| s[0] as i8) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -244,31 +246,31 @@ impl<'a> Cursor<'a> { |
|
|
|
get_f64_ne: f64 = from_ne_bytes, |
|
|
|
get_f64_ne: f64 = from_ne_bytes, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn expect(&mut self, s: &[u8]) -> Result<(), Error> { |
|
|
|
pub fn expect(&mut self, s: &[u8]) -> Result<()> { |
|
|
|
if self.buffer.starts_with(s) { |
|
|
|
if self.buffer.starts_with(s) { |
|
|
|
self.advance(s.len())?; |
|
|
|
self.advance(s.len())?; |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Err(Error::Expect) |
|
|
|
Err(CursorError::Expect) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn expect_empty(&self) -> Result<(), Error> { |
|
|
|
pub fn expect_empty(&self) -> Result<()> { |
|
|
|
if self.has_remaining() { |
|
|
|
if self.has_remaining() { |
|
|
|
Err(Error::ExpectEmpty) |
|
|
|
Err(CursorError::ExpectEmpty) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn take_while<F>(&mut self, mut cond: F) -> Result<&'a [u8], Error> |
|
|
|
pub fn take_while<F>(&mut self, mut cond: F) -> Result<&'a [u8]> |
|
|
|
where |
|
|
|
where |
|
|
|
F: FnMut(u8) -> bool, |
|
|
|
F: FnMut(u8) -> bool, |
|
|
|
{ |
|
|
|
{ |
|
|
|
self.buffer |
|
|
|
self.buffer |
|
|
|
.iter() |
|
|
|
.iter() |
|
|
|
.position(|&i| !cond(i)) |
|
|
|
.position(|&i| !cond(i)) |
|
|
|
.ok_or(Error::UnexpectedEnd) |
|
|
|
.ok_or(CursorError::UnexpectedEnd) |
|
|
|
.and_then(|n| self.get_bytes(n)) |
|
|
|
.and_then(|n| self.get_bytes(n)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -283,7 +285,7 @@ impl<'a> Cursor<'a> { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_key_value_raw(&mut self) -> Result<&'a [u8], Error> { |
|
|
|
pub fn get_key_value_raw(&mut self) -> Result<&'a [u8]> { |
|
|
|
let mut cur = *self; |
|
|
|
let mut cur = *self; |
|
|
|
match cur.get_u8()? { |
|
|
|
match cur.get_u8()? { |
|
|
|
b'\\' => { |
|
|
|
b'\\' => { |
|
|
@ -291,19 +293,19 @@ impl<'a> Cursor<'a> { |
|
|
|
*self = cur; |
|
|
|
*self = cur; |
|
|
|
Ok(value) |
|
|
|
Ok(value) |
|
|
|
} |
|
|
|
} |
|
|
|
_ => Err(Error::InvalidTableValue), |
|
|
|
_ => Err(CursorError::InvalidTableValue), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_key_value<T: GetKeyValue<'a>>(&mut self) -> Result<T, Error> { |
|
|
|
pub fn get_key_value<T: GetKeyValue<'a>>(&mut self) -> Result<T> { |
|
|
|
T::get_key_value(self) |
|
|
|
T::get_key_value(self) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn skip_key_value<T: GetKeyValue<'a>>(&mut self) -> Result<(), Error> { |
|
|
|
pub fn skip_key_value<T: GetKeyValue<'a>>(&mut self) -> Result<()> { |
|
|
|
T::get_key_value(self).map(|_| ()) |
|
|
|
T::get_key_value(self).map(|_| ()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_key_raw(&mut self) -> Result<&'a [u8], Error> { |
|
|
|
pub fn get_key_raw(&mut self) -> Result<&'a [u8]> { |
|
|
|
let mut cur = *self; |
|
|
|
let mut cur = *self; |
|
|
|
match cur.get_u8() { |
|
|
|
match cur.get_u8() { |
|
|
|
Ok(b'\\') => { |
|
|
|
Ok(b'\\') => { |
|
|
@ -311,49 +313,37 @@ impl<'a> Cursor<'a> { |
|
|
|
*self = cur; |
|
|
|
*self = cur; |
|
|
|
Ok(value) |
|
|
|
Ok(value) |
|
|
|
} |
|
|
|
} |
|
|
|
Ok(b'\n') | Err(Error::UnexpectedEnd) => Err(Error::TableEnd), |
|
|
|
Ok(b'\n') | Err(CursorError::UnexpectedEnd) => Err(CursorError::TableEnd), |
|
|
|
_ => Err(Error::InvalidTableKey), |
|
|
|
_ => Err(CursorError::InvalidTableKey), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_key<T: GetKeyValue<'a>>(&mut self) -> Result<(&'a [u8], T), Error> { |
|
|
|
pub fn get_key<T: GetKeyValue<'a>>(&mut self) -> Result<(&'a [u8], T)> { |
|
|
|
Ok((self.get_key_raw()?, self.get_key_value()?)) |
|
|
|
Ok((self.get_key_raw()?, self.get_key_value()?)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub trait PutKeyValue { |
|
|
|
pub trait PutKeyValue { |
|
|
|
fn put_key_value<'a, 'b>( |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>>; |
|
|
|
&self, |
|
|
|
|
|
|
|
cur: &'b mut CursorMut<'a>, |
|
|
|
|
|
|
|
) -> Result<&'b mut CursorMut<'a>, Error>; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<T> PutKeyValue for &T |
|
|
|
impl<T> PutKeyValue for &T |
|
|
|
where |
|
|
|
where |
|
|
|
T: PutKeyValue, |
|
|
|
T: PutKeyValue, |
|
|
|
{ |
|
|
|
{ |
|
|
|
fn put_key_value<'a, 'b>( |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>> { |
|
|
|
&self, |
|
|
|
|
|
|
|
cur: &'b mut CursorMut<'a>, |
|
|
|
|
|
|
|
) -> Result<&'b mut CursorMut<'a>, Error> { |
|
|
|
|
|
|
|
(*self).put_key_value(cur) |
|
|
|
(*self).put_key_value(cur) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl PutKeyValue for &str { |
|
|
|
impl PutKeyValue for &str { |
|
|
|
fn put_key_value<'a, 'b>( |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>> { |
|
|
|
&self, |
|
|
|
|
|
|
|
cur: &'b mut CursorMut<'a>, |
|
|
|
|
|
|
|
) -> Result<&'b mut CursorMut<'a>, Error> { |
|
|
|
|
|
|
|
cur.put_str(self) |
|
|
|
cur.put_str(self) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl PutKeyValue for bool { |
|
|
|
impl PutKeyValue for bool { |
|
|
|
fn put_key_value<'a, 'b>( |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>> { |
|
|
|
&self, |
|
|
|
|
|
|
|
cur: &'b mut CursorMut<'a>, |
|
|
|
|
|
|
|
) -> Result<&'b mut CursorMut<'a>, Error> { |
|
|
|
|
|
|
|
cur.put_u8(if *self { b'1' } else { b'0' }) |
|
|
|
cur.put_u8(if *self { b'1' } else { b'0' }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -361,7 +351,7 @@ impl PutKeyValue for bool { |
|
|
|
macro_rules! impl_put_key_value { |
|
|
|
macro_rules! impl_put_key_value { |
|
|
|
($($t:ty),+ $(,)?) => { |
|
|
|
($($t:ty),+ $(,)?) => { |
|
|
|
$(impl PutKeyValue for $t { |
|
|
|
$(impl PutKeyValue for $t { |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>, Error> { |
|
|
|
fn put_key_value<'a, 'b>(&self, cur: &'b mut CursorMut<'a>) -> Result<&'b mut CursorMut<'a>> { |
|
|
|
cur.put_as_str(self) |
|
|
|
cur.put_as_str(self) |
|
|
|
} |
|
|
|
} |
|
|
|
})+ |
|
|
|
})+ |
|
|
@ -391,7 +381,7 @@ pub struct CursorMut<'a> { |
|
|
|
macro_rules! impl_put { |
|
|
|
macro_rules! impl_put { |
|
|
|
($($n:ident: $t:ty = $f:ident),+ $(,)?) => ( |
|
|
|
($($n:ident: $t:ty = $f:ident),+ $(,)?) => ( |
|
|
|
$(#[inline] |
|
|
|
$(#[inline] |
|
|
|
pub fn $n(&mut self, n: $t) -> Result<&mut Self, Error> { |
|
|
|
pub fn $n(&mut self, n: $t) -> Result<&mut Self> { |
|
|
|
self.put_array(&n.$f()) |
|
|
|
self.put_array(&n.$f()) |
|
|
|
})+ |
|
|
|
})+ |
|
|
|
); |
|
|
|
); |
|
|
@ -411,7 +401,7 @@ impl<'a> CursorMut<'a> { |
|
|
|
self.buffer.len() - self.pos |
|
|
|
self.buffer.len() - self.pos |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn advance<F>(&mut self, count: usize, mut f: F) -> Result<&mut Self, Error> |
|
|
|
pub fn advance<F>(&mut self, count: usize, mut f: F) -> Result<&mut Self> |
|
|
|
where |
|
|
|
where |
|
|
|
F: FnMut(&mut [u8]), |
|
|
|
F: FnMut(&mut [u8]), |
|
|
|
{ |
|
|
|
{ |
|
|
@ -420,37 +410,37 @@ impl<'a> CursorMut<'a> { |
|
|
|
self.pos += count; |
|
|
|
self.pos += count; |
|
|
|
Ok(self) |
|
|
|
Ok(self) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Err(Error::UnexpectedEnd) |
|
|
|
Err(CursorError::UnexpectedEnd) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_bytes(&mut self, s: &[u8]) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_bytes(&mut self, s: &[u8]) -> Result<&mut Self> { |
|
|
|
self.advance(s.len(), |i| { |
|
|
|
self.advance(s.len(), |i| { |
|
|
|
i.copy_from_slice(s); |
|
|
|
i.copy_from_slice(s); |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_array<const N: usize>(&mut self, s: &[u8; N]) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_array<const N: usize>(&mut self, s: &[u8; N]) -> Result<&mut Self> { |
|
|
|
self.advance(N, |i| { |
|
|
|
self.advance(N, |i| { |
|
|
|
i.copy_from_slice(s); |
|
|
|
i.copy_from_slice(s); |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_str(&mut self, s: &str) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_str(&mut self, s: &str) -> Result<&mut Self> { |
|
|
|
self.put_bytes(s.as_bytes()) |
|
|
|
self.put_bytes(s.as_bytes()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_cstr(&mut self, s: &str) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_cstr(&mut self, s: &str) -> Result<&mut Self> { |
|
|
|
self.put_str(s)?.put_u8(0) |
|
|
|
self.put_str(s)?.put_u8(0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[inline(always)] |
|
|
|
#[inline(always)] |
|
|
|
pub fn put_u8(&mut self, n: u8) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_u8(&mut self, n: u8) -> Result<&mut Self> { |
|
|
|
self.put_array(&[n]) |
|
|
|
self.put_array(&[n]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[inline(always)] |
|
|
|
#[inline(always)] |
|
|
|
pub fn put_i8(&mut self, n: i8) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_i8(&mut self, n: i8) -> Result<&mut Self> { |
|
|
|
self.put_u8(n as u8) |
|
|
|
self.put_u8(n as u8) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -483,23 +473,23 @@ impl<'a> CursorMut<'a> { |
|
|
|
put_f64_ne: f64 = to_ne_bytes, |
|
|
|
put_f64_ne: f64 = to_ne_bytes, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_as_str<T: fmt::Display>(&mut self, value: T) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_as_str<T: fmt::Display>(&mut self, value: T) -> Result<&mut Self> { |
|
|
|
write!(self, "{}", value).map_err(|_| Error::UnexpectedEnd)?; |
|
|
|
write!(self, "{}", value).map_err(|_| CursorError::UnexpectedEnd)?; |
|
|
|
Ok(self) |
|
|
|
Ok(self) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_key_value<T: PutKeyValue>(&mut self, value: T) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_key_value<T: PutKeyValue>(&mut self, value: T) -> Result<&mut Self> { |
|
|
|
value.put_key_value(self) |
|
|
|
value.put_key_value(self) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_key_raw(&mut self, key: &str, value: &[u8]) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_key_raw(&mut self, key: &str, value: &[u8]) -> Result<&mut Self> { |
|
|
|
self.put_u8(b'\\')? |
|
|
|
self.put_u8(b'\\')? |
|
|
|
.put_str(key)? |
|
|
|
.put_str(key)? |
|
|
|
.put_u8(b'\\')? |
|
|
|
.put_u8(b'\\')? |
|
|
|
.put_bytes(value) |
|
|
|
.put_bytes(value) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn put_key<T: PutKeyValue>(&mut self, key: &str, value: T) -> Result<&mut Self, Error> { |
|
|
|
pub fn put_key<T: PutKeyValue>(&mut self, key: &str, value: T) -> Result<&mut Self> { |
|
|
|
self.put_u8(b'\\')? |
|
|
|
self.put_u8(b'\\')? |
|
|
|
.put_str(key)? |
|
|
|
.put_str(key)? |
|
|
|
.put_u8(b'\\')? |
|
|
|
.put_u8(b'\\')? |
|
|
@ -520,7 +510,7 @@ mod tests { |
|
|
|
use super::*; |
|
|
|
use super::*; |
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn cursor() -> Result<(), Error> { |
|
|
|
fn cursor() -> Result<()> { |
|
|
|
let mut buf = [0; 64]; |
|
|
|
let mut buf = [0; 64]; |
|
|
|
let n = CursorMut::new(&mut buf) |
|
|
|
let n = CursorMut::new(&mut buf) |
|
|
|
.put_bytes(b"12345678")? |
|
|
|
.put_bytes(b"12345678")? |
|
|
@ -541,13 +531,13 @@ mod tests { |
|
|
|
assert_eq!(cur.get_u8(), Ok(0x7f)); |
|
|
|
assert_eq!(cur.get_u8(), Ok(0x7f)); |
|
|
|
assert_eq!(cur.get_i8(), Ok(-128)); |
|
|
|
assert_eq!(cur.get_i8(), Ok(-128)); |
|
|
|
assert_eq!(cur.get_u32_le(), Ok(0x44332211)); |
|
|
|
assert_eq!(cur.get_u32_le(), Ok(0x44332211)); |
|
|
|
assert_eq!(cur.get_u8(), Err(Error::UnexpectedEnd)); |
|
|
|
assert_eq!(cur.get_u8(), Err(CursorError::UnexpectedEnd)); |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn key() -> Result<(), Error> { |
|
|
|
fn key() -> Result<()> { |
|
|
|
let mut buf = [0; 512]; |
|
|
|
let mut buf = [0; 512]; |
|
|
|
let n = CursorMut::new(&mut buf) |
|
|
|
let n = CursorMut::new(&mut buf) |
|
|
|
.put_key("p", 49)? |
|
|
|
.put_key("p", 49)? |
|
|
@ -574,7 +564,7 @@ mod tests { |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"gamedir"[..], "valve"))); |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"gamedir"[..], "valve"))); |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"password"[..], false))); |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"password"[..], false))); |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"host"[..], "test"))); |
|
|
|
assert_eq!(cur.get_key(), Ok((&b"host"[..], "test"))); |
|
|
|
assert_eq!(cur.get_key::<&[u8]>(), Err(Error::TableEnd)); |
|
|
|
assert_eq!(cur.get_key::<&[u8]>(), Err(CursorError::TableEnd)); |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|