use std::{error, fmt, num};
use noodles::core::Position;
use super::num::write_i32_le;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum EncodeError {
Invalid(num::TryFromIntError),
}
impl error::Error for EncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Self::Invalid(e) => Some(e),
}
}
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Invalid(_) => write!(f, "invalid input"),
}
}
}
pub(super) fn write_position(
dst: &mut Vec<u8>,
position: Option<Position>,
) -> Result<(), EncodeError> {
const MISSING: i32 = -1;
let n = if let Some(position) = position {
let m = usize::from(position) - 1;
i32::try_from(m).map_err(EncodeError::Invalid)?
} else {
MISSING
};
write_i32_le(dst, n);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_write_position() -> Result<(), Box<dyn std::error::Error>> {
fn t(
buf: &mut Vec<u8>,
position: Option<Position>,
expected: &[u8],
) -> Result<(), EncodeError> {
buf.clear();
write_position(buf, position)?;
assert_eq!(buf, expected);
Ok(())
}
let mut buf = Vec::new();
t(&mut buf, None, &[0xff, 0xff, 0xff, 0xff])?;
t(&mut buf, Some(Position::MIN), &[0x00, 0x00, 0x00, 0x00])?;
t(&mut buf, Position::try_from(8).map(Some)?, &[0x07, 0x00, 0x00, 0x00])?;
Ok(())
}
}