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 {}
/// Mime type supported by clipboard.
#[derive(Clone, Eq, PartialEq, Debug, Default)]
#[repr(u8)]
pub enum MimeType {
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
pub enum Text {
#[default]
/// text/plain;charset=utf-8 mime type.
///
/// The primary mime type used by most clients
TextPlainUtf8,
TextPlainUtf8 = 0,
/// UTF8_STRING mime type.
///
/// Some X11 clients are using only this mime type, so we
/// should have it as a fallback just in case.
Utf8String,
Utf8String = 1,
/// text/plain mime type.
///
/// 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(Cow<'static, str>),
}
impl Default for MimeType {
fn default() -> Self {
MimeType::Text(Text::default())
}
}
impl AsRef<str> for MimeType {
fn as_ref(&self) -> &str {
match self {
MimeType::Other(s) => s.as_ref(),
m => ALLOWED_TEXT_MIME_TYPES[m.discriminant() as usize],
m => ALLOWED_TEXT_MIME_TYPES[m.discriminant()],
}
}
}
impl MimeType {
fn discriminant(&self) -> u8 {
unsafe { *(self as *const Self as *const u8) }
fn discriminant(&self) -> usize {
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 {
match self {
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 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);
@ -16,8 +16,10 @@ impl TryFrom<(Vec<u8>, MimeType)> for Text {
// Post-process the content according to mime type.
let content = match mime_type {
MimeType::TextPlainUtf8 | MimeType::TextPlain => normalize_to_lf(content),
MimeType::Utf8String => content,
MimeType::Text(mime::Text::TextPlainUtf8 | mime::Text::TextPlain) => {
normalize_to_lf(content)
},
MimeType::Text(mime::Text::Utf8String) => content,
MimeType::Other(_) => return Err(Error),
};
Ok(Text(content))
@ -26,7 +28,11 @@ impl TryFrom<(Vec<u8>, MimeType)> for Text {
impl AllowedMimeTypes for Text {
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]>> {
match mime_type {
MimeType::TextPlainUtf8 | MimeType::Utf8String | MimeType::TextPlain => {
Some(Cow::Owned(self.0.as_bytes().to_owned()))
},
MimeType::Text(
mime::Text::TextPlainUtf8 | mime::Text::Utf8String | mime::Text::TextPlain,
) => Some(Cow::Owned(self.0.as_bytes().to_owned())),
MimeType::Other(_) => None,
}
}