pub use encoding_rs::{Encoding, SHIFT_JIS, UTF_8, WINDOWS_1252};
use std::{borrow::Cow, fmt};
#[derive(Eq, PartialEq)]
#[repr(transparent)]
pub struct SwfStr {
string: [u8],
}
impl SwfStr {
#[inline]
pub const fn from_bytes(string: &[u8]) -> &Self {
unsafe { &*(string as *const [u8] as *const Self) }
}
#[inline]
pub fn from_bytes_null_terminated(string: &[u8]) -> Option<&Self> {
string
.iter()
.position(|&c| c == 0)
.map(|i| Self::from_bytes(&string[..i]))
}
#[inline]
pub const fn from_utf8_str(string: &str) -> &Self {
Self::from_bytes(string.as_bytes())
}
#[inline]
pub fn from_utf8_str_null_terminated(string: &str) -> Option<&Self> {
Self::from_bytes_null_terminated(string.as_bytes())
}
pub fn from_str_with_encoding<'a>(
string: &'a str,
encoding: &'static Encoding,
) -> Option<&'a Self> {
if let (Cow::Borrowed(s), _, false) = encoding.encode(string) {
Some(Self::from_bytes(s))
} else {
None
}
}
#[inline]
pub fn encoding_for_version(swf_version: u8) -> &'static Encoding {
if swf_version >= 6 {
UTF_8
} else {
WINDOWS_1252
}
}
#[inline]
pub const fn as_bytes(&self) -> &[u8] {
&self.string
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.string.is_empty()
}
#[inline]
pub const fn len(&self) -> usize {
self.string.len()
}
#[inline]
pub fn to_str_lossy(&self, encoding: &'static Encoding) -> Cow<'_, str> {
encoding.decode_without_bom_handling(&self.string).0
}
#[inline]
pub fn to_string_lossy(&self, encoding: &'static Encoding) -> String {
self.to_str_lossy(encoding).into_owned()
}
}
impl<'a> Default for &'a SwfStr {
fn default() -> &'a SwfStr {
SwfStr::from_bytes(&[])
}
}
impl<'a> From<&'a str> for &'a SwfStr {
fn from(s: &'a str) -> &'a SwfStr {
SwfStr::from_utf8_str(s)
}
}
impl<T: ?Sized + AsRef<str>> PartialEq<T> for SwfStr {
fn eq(&self, other: &T) -> bool {
&self.string == other.as_ref().as_bytes()
}
}
impl fmt::Debug for SwfStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Write::write_char(f, '"')?;
for chr in self
.string
.iter()
.flat_map(|&c| std::ascii::escape_default(c))
{
fmt::Write::write_char(f, char::from(chr))?;
}
fmt::Write::write_char(f, '"')
}
}