Refactor mime type handling

- Remove `MimeWrapper` from public api
- Use `mime::Mime` in public api instead
This commit is contained in:
Waffle 2021-01-13 15:59:51 +03:00
parent 3c12e56f8d
commit 555bfc93d5
10 changed files with 139 additions and 70 deletions

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{MimeWrapper, PhotoSize}; use crate::types::PhotoSize;
/// This object represents an animation file (GIF or H.264/MPEG-4 AVC video /// This object represents an animation file (GIF or H.264/MPEG-4 AVC video
/// without sound). /// without sound).
@ -33,7 +34,8 @@ pub struct Animation {
pub file_name: Option<String>, pub file_name: Option<String>,
/// A MIME type of the file as defined by a sender. /// A MIME type of the file as defined by a sender.
pub mime_type: Option<MimeWrapper>, #[serde(with = "crate::types::non_telegram_types::mime::opt_deser")]
pub mime_type: Option<Mime>,
/// A size of a file. /// A size of a file.
pub file_size: Option<u32>, pub file_size: Option<u32>,
@ -108,7 +110,7 @@ impl Animation {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = Some(val); self.mime_type = Some(val);
self self
} }
@ -155,7 +157,7 @@ mod tests {
file_size: Some(3452), file_size: Some(3452),
}), }),
file_name: Some("some".to_string()), file_name: Some("some".to_string()),
mime_type: Some(MimeWrapper("video/gif".parse().unwrap())), mime_type: Some("video/gif".parse().unwrap()),
file_size: Some(6500), file_size: Some(6500),
}; };
let actual = serde_json::from_str::<Animation>(json).unwrap(); let actual = serde_json::from_str::<Animation>(json).unwrap();

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{MimeWrapper, PhotoSize}; use crate::types::PhotoSize;
/// This object represents an audio file to be treated as music by the Telegram /// This object represents an audio file to be treated as music by the Telegram
/// clients. /// clients.
@ -27,7 +28,8 @@ pub struct Audio {
pub title: Option<String>, pub title: Option<String>,
/// A MIME type of the file as defined by a sender. /// A MIME type of the file as defined by a sender.
pub mime_type: Option<MimeWrapper>, #[serde(with = "crate::types::non_telegram_types::mime::opt_deser")]
pub mime_type: Option<Mime>,
/// A size of a file. /// A size of a file.
pub file_size: Option<u32>, pub file_size: Option<u32>,
@ -91,7 +93,7 @@ impl Audio {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = Some(val); self.mime_type = Some(val);
self self
} }
@ -135,7 +137,7 @@ mod tests {
duration: 60, duration: 60,
performer: Some("Performer".to_string()), performer: Some("Performer".to_string()),
title: Some("Title".to_string()), title: Some("Title".to_string()),
mime_type: Some(serde_json::from_str("\"application/zip\"").unwrap()), mime_type: Some("application/zip".parse().unwrap()),
file_size: Some(123_456), file_size: Some(123_456),
thumb: Some(PhotoSize { thumb: Some(PhotoSize {
file_id: "id".to_string(), file_id: "id".to_string(),

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{MimeWrapper, PhotoSize}; use crate::types::PhotoSize;
/// This object represents a general file (as opposed to [photos], [voice /// This object represents a general file (as opposed to [photos], [voice
/// messages] and [audio files]). /// messages] and [audio files]).
@ -28,7 +29,8 @@ pub struct Document {
pub file_name: Option<String>, pub file_name: Option<String>,
/// A MIME type of the file as defined by a sender. /// A MIME type of the file as defined by a sender.
pub mime_type: Option<MimeWrapper>, #[serde(with = "crate::types::non_telegram_types::mime::opt_deser")]
pub mime_type: Option<Mime>,
/// A size of a file. /// A size of a file.
pub file_size: Option<u32>, pub file_size: Option<u32>,
@ -79,7 +81,7 @@ impl Document {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = Some(val); self.mime_type = Some(val);
self self
} }

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{InlineKeyboardMarkup, InputMessageContent, MimeWrapper, ParseMode}; use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
/// Represents a link to a file. /// Represents a link to a file.
/// ///
@ -35,7 +36,8 @@ pub struct InlineQueryResultDocument {
/// Mime type of the content of the file, either `application/pdf` or /// Mime type of the content of the file, either `application/pdf` or
/// `application/zip`. /// `application/zip`.
pub mime_type: MimeWrapper, #[serde(with = "crate::types::non_telegram_types::mime::deser")]
pub mime_type: Mime,
/// Short description of the result. /// Short description of the result.
pub description: Option<String>, pub description: Option<String>,
@ -94,7 +96,7 @@ impl InlineQueryResultDocument {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = val; self.mime_type = val;
self self
} }

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{InlineKeyboardMarkup, InputMessageContent, MimeWrapper, ParseMode}; use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
/// Represents a link to a page containing an embedded video player or a video /// Represents a link to a page containing an embedded video player or a video
/// file. /// file.
@ -20,7 +21,8 @@ pub struct InlineQueryResultVideo {
pub video_url: String, pub video_url: String,
/// Mime type of the content of video url, `text/html` or `video/mp4`. /// Mime type of the content of video url, `text/html` or `video/mp4`.
pub mime_type: MimeWrapper, #[serde(with = "crate::types::non_telegram_types::mime::deser")]
pub mime_type: Mime,
/// URL of the thumbnail (jpeg only) for the video. /// URL of the thumbnail (jpeg only) for the video.
pub thumb_url: String, pub thumb_url: String,
@ -69,7 +71,7 @@ impl InlineQueryResultVideo {
pub fn new<S1, S2, S3, S4>( pub fn new<S1, S2, S3, S4>(
id: S1, id: S1,
video_url: S2, video_url: S2,
mime_type: MimeWrapper, mime_type: Mime,
thumb_url: S3, thumb_url: S3,
title: S4, title: S4,
) -> Self ) -> Self
@ -112,7 +114,7 @@ impl InlineQueryResultVideo {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = val; self.mime_type = val;
self self
} }

View file

@ -0,0 +1,100 @@
use std::fmt;
use mime::Mime;
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
pub(crate) mod deser {
use mime::Mime;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::{MimeDe, MimeSer};
pub(crate) fn serialize<S>(
this: &Mime,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
MimeSer(this).serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Mime, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
MimeDe::deserialize(deserializer).map(|MimeDe(m)| m)
}
}
pub(crate) mod opt_deser {
use mime::Mime;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::{MimeDe, MimeSer};
pub(crate) fn serialize<S>(
this: &Option<Mime>,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
this.as_ref().map(MimeSer).serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Option<Mime>, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
Option::<MimeDe>::deserialize(deserializer).map(|opt| opt.map(|MimeDe(m)| m))
}
}
struct MimeSer<'a>(&'a Mime);
impl Serialize for MimeSer<'_> {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
serializer.serialize_str(self.0.as_ref())
}
}
struct MimeVisitor;
impl<'a> Visitor<'a> for MimeVisitor {
type Value = MimeDe;
fn expecting(
&self,
formatter: &mut fmt::Formatter<'_>,
) -> Result<(), serde::export::fmt::Error> {
formatter.write_str("mime type")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v.parse::<Mime>() {
Ok(mime_type) => Ok(MimeDe(mime_type)),
Err(e) => Err(E::custom(e)),
}
}
}
struct MimeDe(Mime);
impl<'de> Deserialize<'de> for MimeDe {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(MimeVisitor)
}
}

View file

@ -1,44 +0,0 @@
use derive_more::From;
use mime::Mime;
use serde::{de::Visitor, export::Formatter, Deserialize, Deserializer, Serialize, Serializer};
/// Serializable & deserializable `MIME` wrapper.
#[derive(Clone, Debug, Eq, Hash, PartialEq, From)]
pub struct MimeWrapper(pub Mime);
impl Serialize for MimeWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
serializer.serialize_str(self.0.as_ref())
}
}
struct MimeVisitor;
impl<'a> Visitor<'a> for MimeVisitor {
type Value = MimeWrapper;
fn expecting(&self, formatter: &mut Formatter<'_>) -> Result<(), serde::export::fmt::Error> {
formatter.write_str("mime type")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v.parse::<Mime>() {
Ok(mime_type) => Ok(MimeWrapper(mime_type)),
Err(e) => Err(E::custom(e)),
}
}
}
impl<'de> Deserialize<'de> for MimeWrapper {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(MimeVisitor)
}
}

View file

@ -1,9 +1,9 @@
pub use country_code::*; pub use country_code::*;
pub use currency::*; pub use currency::*;
pub use mime_wrapper::*;
pub use non_strict_vec::*; pub use non_strict_vec::*;
mod country_code; mod country_code;
mod currency; mod currency;
mod mime_wrapper;
mod non_strict_vec; mod non_strict_vec;
pub(crate) mod mime;

View file

@ -1,6 +1,7 @@
use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::types::{MimeWrapper, PhotoSize}; use crate::types::PhotoSize;
/// This object represents a video file. /// This object represents a video file.
/// ///
@ -29,7 +30,8 @@ pub struct Video {
pub thumb: Option<PhotoSize>, pub thumb: Option<PhotoSize>,
/// Mime type of a file as defined by sender. /// Mime type of a file as defined by sender.
pub mime_type: Option<MimeWrapper>, #[serde(with = "crate::types::non_telegram_types::mime::opt_deser")]
pub mime_type: Option<Mime>,
/// File size. /// File size.
pub file_size: Option<u32>, pub file_size: Option<u32>,
@ -95,7 +97,7 @@ impl Video {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = Some(val); self.mime_type = Some(val);
self self
} }

View file

@ -1,4 +1,4 @@
use crate::types::MimeWrapper; use mime::Mime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// This object represents a voice note. /// This object represents a voice note.
@ -19,7 +19,8 @@ pub struct Voice {
pub duration: u32, pub duration: u32,
/// MIME type of the file as defined by sender. /// MIME type of the file as defined by sender.
pub mime_type: Option<MimeWrapper>, #[serde(with = "crate::types::non_telegram_types::mime::opt_deser")]
pub mime_type: Option<Mime>,
/// File size. /// File size.
pub file_size: Option<u64>, pub file_size: Option<u64>,
@ -61,7 +62,7 @@ impl Voice {
self self
} }
pub fn mime_type(mut self, val: MimeWrapper) -> Self { pub fn mime_type(mut self, val: Mime) -> Self {
self.mime_type = Some(val); self.mime_type = Some(val);
self self
} }