From a74fc5ba675bba862a7ce3bf4747cc0f9443a5c0 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 28 Feb 2024 15:17:37 -0500 Subject: [PATCH] refactor: Text mimes as their own type --- src/mime.rs | 36 +++++++++++++++++++++++++----------- src/text.rs | 20 +++++++++++++------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/mime.rs b/src/mime.rs index 40be7ef..60377f2 100644 --- a/src/mime.rs +++ b/src/mime.rs @@ -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 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()]), } } } diff --git a/src/text.rs b/src/text.rs index a092e2b..4943b92 100644 --- a/src/text.rs +++ b/src/text.rs @@ -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, 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, 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> { 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, } }