refactor: Text mimes as their own type

This commit is contained in:
Ashley Wulber 2024-02-28 15:17:37 -05:00
parent 84229d0503
commit a74fc5ba67
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
2 changed files with 38 additions and 18 deletions

View file

@ -16,40 +16,54 @@ impl fmt::Display for Error {
impl error::Error for Error {} impl error::Error for Error {}
/// Mime type supported by clipboard. #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
#[derive(Clone, Eq, PartialEq, Debug, Default)] pub enum Text {
#[repr(u8)]
pub enum MimeType {
#[default] #[default]
/// text/plain;charset=utf-8 mime type. /// text/plain;charset=utf-8 mime type.
/// ///
/// The primary mime type used by most clients /// The primary mime type used by most clients
TextPlainUtf8, TextPlainUtf8 = 0,
/// UTF8_STRING mime type. /// UTF8_STRING mime type.
/// ///
/// Some X11 clients are using only this mime type, so we /// Some X11 clients are using only this mime type, so we
/// should have it as a fallback just in case. /// should have it as a fallback just in case.
Utf8String, Utf8String = 1,
/// text/plain mime type. /// text/plain mime type.
/// ///
/// Fallback without charset parameter. /// Fallback without charset parameter.
TextPlain, TextPlain = 2,
}
/// Mime type supported by clipboard.
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum MimeType {
/// Text mime type.
Text(Text),
/// Other mime type. /// Other mime type.
Other(Cow<'static, str>), Other(Cow<'static, str>),
} }
impl Default for MimeType {
fn default() -> Self {
MimeType::Text(Text::default())
}
}
impl AsRef<str> for MimeType { impl AsRef<str> for MimeType {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
match self { match self {
MimeType::Other(s) => s.as_ref(), MimeType::Other(s) => s.as_ref(),
m => ALLOWED_TEXT_MIME_TYPES[m.discriminant() as usize], m => ALLOWED_TEXT_MIME_TYPES[m.discriminant()],
} }
} }
} }
impl MimeType { impl MimeType {
fn discriminant(&self) -> u8 { fn discriminant(&self) -> usize {
unsafe { *(self as *const Self as *const u8) } match self {
MimeType::Text(t) => *t as usize,
MimeType::Other(_) => 3,
}
} }
} }
@ -87,7 +101,7 @@ impl std::fmt::Display for MimeType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
MimeType::Other(m) => write!(f, "{}", m), MimeType::Other(m) => write!(f, "{}", m),
m => write!(f, "{}", ALLOWED_TEXT_MIME_TYPES[m.discriminant() as usize]), m => write!(f, "{}", ALLOWED_TEXT_MIME_TYPES[m.discriminant()]),
} }
} }
} }

View file

@ -1,6 +1,6 @@
use std::borrow::Cow; use std::borrow::Cow;
use crate::mime::{normalize_to_lf, AllowedMimeTypes, AsMimeTypes, Error, MimeType}; use crate::mime::{self, normalize_to_lf, AllowedMimeTypes, AsMimeTypes, Error, MimeType};
pub struct Text(pub String); pub struct Text(pub String);
@ -16,8 +16,10 @@ impl TryFrom<(Vec<u8>, MimeType)> for Text {
// Post-process the content according to mime type. // Post-process the content according to mime type.
let content = match mime_type { let content = match mime_type {
MimeType::TextPlainUtf8 | MimeType::TextPlain => normalize_to_lf(content), MimeType::Text(mime::Text::TextPlainUtf8 | mime::Text::TextPlain) => {
MimeType::Utf8String => content, normalize_to_lf(content)
},
MimeType::Text(mime::Text::Utf8String) => content,
MimeType::Other(_) => return Err(Error), MimeType::Other(_) => return Err(Error),
}; };
Ok(Text(content)) Ok(Text(content))
@ -26,7 +28,11 @@ impl TryFrom<(Vec<u8>, MimeType)> for Text {
impl AllowedMimeTypes for Text { impl AllowedMimeTypes for Text {
fn allowed() -> Cow<'static, [MimeType]> { fn allowed() -> Cow<'static, [MimeType]> {
Cow::Borrowed(&[MimeType::TextPlainUtf8, MimeType::Utf8String, MimeType::TextPlain]) Cow::Borrowed(&[
MimeType::Text(mime::Text::TextPlainUtf8),
MimeType::Text(mime::Text::Utf8String),
MimeType::Text(mime::Text::TextPlain),
])
} }
} }
@ -37,9 +43,9 @@ impl AsMimeTypes for Text {
fn as_bytes(&self, mime_type: &MimeType) -> Option<Cow<'static, [u8]>> { fn as_bytes(&self, mime_type: &MimeType) -> Option<Cow<'static, [u8]>> {
match mime_type { match mime_type {
MimeType::TextPlainUtf8 | MimeType::Utf8String | MimeType::TextPlain => { MimeType::Text(
Some(Cow::Owned(self.0.as_bytes().to_owned())) mime::Text::TextPlainUtf8 | mime::Text::Utf8String | mime::Text::TextPlain,
}, ) => Some(Cow::Owned(self.0.as_bytes().to_owned())),
MimeType::Other(_) => None, MimeType::Other(_) => None,
} }
} }