use crate::dev::*;
pub type LocalizedString = u32;
#[derive(Debug)]
pub struct ESMString(pub String);
impl Parse<&[u8]> for ESMString {
fn parse(i: &[u8]) -> IResult<&[u8], Self, nom::error::Error<&[u8]>> {
if i.is_empty() {
Ok((i, Self(String::new())))
} else {
let (_, left) = take(i.len()-1)(i)?;
let s = String::from_utf8_lossy(left).to_string();
Ok((&[], Self(s)))
}
}
}
impl std::fmt::Display for ESMString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(PartialEq, Eq, Clone)]
pub struct SizedString32(pub String);
impl Parse<&[u8]> for SizedString32 {
fn parse(i: &[u8]) -> nom::IResult<&[u8], Self, nom::error::Error<&[u8]>> {
let (i, len) = le_u32(i)?;
let (i, s) = take(len)(i)?;
let s = String::from_utf8_lossy(s).to_string().replace('\0', "");
Ok((i, SizedString32(s)))
}
}
impl SizedString32 {
pub fn parse_empty_as_none(i: &[u8]) -> IResult<&[u8], Option<String>> {
let (i, result) = Self::parse(i)?;
if result.0.is_empty() {
Ok((i, None))
} else {
Ok((i, Some(result.0)))
}
}
}
impl std::fmt::Display for SizedString32 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::Debug for SizedString32 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.0)
}
}
#[derive(PartialEq, Eq, Clone)]
pub struct SizedString16(pub String);
impl Parse<&[u8]> for SizedString16 {
fn parse(i: &[u8]) -> nom::IResult<&[u8], Self, nom::error::Error<&[u8]>> {
let (i, len) = le_u16(i)?;
let (i, s) = take(len)(i)?;
let s = String::from_utf8_lossy(s).to_string().replace('\0', "");
Ok((i, SizedString16(s)))
}
}
impl std::fmt::Display for SizedString16 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::Debug for SizedString16 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.0)
}
}
pub fn parse_ss16(i: &[u8]) -> IResult<&[u8], String> {
let (i, len) = nom::number::complete::le_u16(i)?;
let (i, s) = nom::bytes::complete::take(len)(i)?;
Ok((i, String::from_utf8_lossy(s).to_string()))
}
#[derive(PartialEq, Eq)]
pub struct SizedString8(pub String);
impl Parse<&[u8]> for SizedString8 {
fn parse(i: &[u8]) -> nom::IResult<&[u8], Self, nom::error::Error<&[u8]>> {
let (i, len) = le_u8(i)?;
let (i, s) = take(len)(i)?;
let s = String::from_utf8_lossy(s).to_string().replace('\0', "");
Ok((i, SizedString8(s)))
}
}
impl std::fmt::Display for SizedString8 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::Debug for SizedString8 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.0)
}
}
pub struct StringN {
pub value: String,
}
impl Parse<&[u8]> for StringN {
fn parse(i: &[u8]) -> IResult<&[u8], Self> {
let (i, data) = nom::bytes::complete::take_until("\n")(i)?;
let (i, _) = take(1usize)(i)?;
Ok((i, StringN { value: String::from_utf8_lossy(data).to_string() }))
}
}
impl std::fmt::Debug for StringN {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.value)
}
}