use crate::error::{Result, ZipError};
#[derive(Debug, Clone, Copy)]
pub enum StringEncoding {
Utf8,
Raw,
}
#[derive(Debug, Clone)]
pub struct ZipString {
encoding: StringEncoding,
raw: Vec<u8>,
}
impl ZipString {
pub fn new(raw: Vec<u8>, mut encoding: StringEncoding) -> Self {
if let StringEncoding::Utf8 = encoding {
if std::str::from_utf8(&raw).is_err() {
encoding = StringEncoding::Raw;
}
}
Self { encoding, raw }
}
pub fn as_bytes(&self) -> &[u8] {
&self.raw
}
pub fn encoding(&self) -> StringEncoding {
self.encoding
}
pub fn as_str(&self) -> Result<&str> {
if !matches!(self.encoding, StringEncoding::Utf8) {
return Err(ZipError::StringNotUtf8);
}
Ok(unsafe { std::str::from_utf8_unchecked(&self.raw) })
}
pub fn into_string(self) -> Result<String> {
if !matches!(self.encoding, StringEncoding::Utf8) {
return Err(ZipError::StringNotUtf8);
}
Ok(unsafe { String::from_utf8_unchecked(self.raw) })
}
}
impl From<String> for ZipString {
fn from(value: String) -> Self {
Self { encoding: StringEncoding::Utf8, raw: value.into_bytes() }
}
}
impl From<&str> for ZipString {
fn from(value: &str) -> Self {
Self { encoding: StringEncoding::Utf8, raw: value.as_bytes().to_vec() }
}
}