Merge pull request #41 from teloxide/improve_docs

Improve docs
This commit is contained in:
Temirkhan Myrzamadi 2021-01-21 18:52:16 +06:00 committed by GitHub
commit 8e011b7e60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 2853 additions and 116 deletions

View file

@ -60,3 +60,7 @@ full = ["throttle", "cache_me", "auto_send"]
[package.metadata."docs.rs"] [package.metadata."docs.rs"]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"] rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"]
[[example]]
name = "self_info"
required-features = ["tokio/macros", "tokio/rt-multi-thread", "auto_send"]

View file

@ -1,7 +1,30 @@
<div align="center">
<img src="media/logo.svg" width="250"/>
</div>
# teloxide-core # teloxide-core
[![CI status](https://github.com/teloxide/teloxide-core/workflows/Continuous%20integration/badge.svg)](https://github.com/teloxide/teloxide-core/actions) [![CI status](https://github.com/teloxide/teloxide-core/workflows/Continuous%20integration/badge.svg)](https://github.com/teloxide/teloxide-core/actions)
[![documentation](https://docs.rs/teloxide_core/badge.svg)](https://docs.rs/teloxide_core/)
[![documentation (master)](https://img.shields.io/badge/docs-master-blue)](https://teloxide-core.netlify.com) [![documentation (master)](https://img.shields.io/badge/docs-master-blue)](https://teloxide-core.netlify.com)
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Api Cov](https://img.shields.io/badge/API%20coverage-Up%20to%200.4.9%20(inclusively)-green.svg)](https://core.telegram.org/bots/api)
[![crates.io](https://img.shields.io/crates/v/teloxide_core.svg)](https://crates.io/crates/teloxide_core)
[![Official Chat](https://img.shields.io/badge/official%20chat-t.me%2Fteloxide-blueviolet)](https://t.me/teloxide)
Core part of `teloxide` library.
Core part of the [`teloxide`] library.
This library provides tools for making requests to the [Telegram Bot API]
(Currently, version `4.9` is supported) with ease. The library is fully
asynchronouns and built using [`tokio`].
```toml
teloxide_core = "0.1"
```
_Compiler support: requires rustc 1.49+_
[`teloxide`]: https://docs.rs/teloxide
[Telegram Bot API]: https://core.telegram.org/bots/api
[`tokio`]: https://tokio.rs

23
examples/self_info.rs Normal file
View file

@ -0,0 +1,23 @@
use teloxide_core::{
prelude::*,
types::{DiceEmoji, ParseMode},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let chat_id = std::env::var("CHAT_ID")
.expect("Expected CHAT_ID env var")
.parse::<i64>()?;
let bot = Bot::from_env()
.parse_mode(ParseMode::MarkdownV2)
.auto_send();
let me = bot.get_me().await?;
bot.send_dice(chat_id, DiceEmoji::Dice).await?;
bot.send_message(chat_id, format!("Hi, my name is **{}** 👋", me.first_name))
.await?;
Ok(())
}

BIN
media/example.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
media/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

1907
media/logo.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 61 KiB

View file

@ -8,12 +8,27 @@
//! //!
//! [`Requester`]: crate::requests::Requester //! [`Requester`]: crate::requests::Requester
/// [`AutoSend`] bot adaptor which allows sending a request without calling
/// [`send`].
///
/// [`AutoSend`]: auto_send::AutoSend
/// [`send`]: crate::requests::Request::send
#[cfg(feature = "auto_send")] #[cfg(feature = "auto_send")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "auto_send")))] #[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "auto_send")))]
pub mod auto_send; pub mod auto_send;
/// [`CacheMe`] bot adaptor which caches [`GetMe`] requests.
///
/// [`CacheMe`]: cache_me::CacheMe
/// [`GetMe`]: crate::payloads::GetMe
#[cfg(feature = "cache_me")] #[cfg(feature = "cache_me")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "cache_me")))] #[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "cache_me")))]
pub mod cache_me; pub mod cache_me;
/// [`Throttle`] bot adaptor which allows automatically throttle when hitting
/// API limits.
///
/// [`Throttle`]: throttle::Throttle
#[cfg(feature = "throttle")] #[cfg(feature = "throttle")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "throttle")))] #[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "throttle")))]
pub mod throttle; pub mod throttle;

View file

@ -20,8 +20,8 @@ use crate::{
/// Notes: /// Notes:
/// 1. This wrapper should be the most outer i.e.: `AutoSend<CacheMe<Bot>>` /// 1. This wrapper should be the most outer i.e.: `AutoSend<CacheMe<Bot>>`
/// will automatically send requests, while `CacheMe<AutoSend<Bot>>` - won't. /// will automatically send requests, while `CacheMe<AutoSend<Bot>>` - won't.
/// 2. After first call to `poll` on a request you will unable to access payload /// 2. After first call to `poll` on a request you will be unable to access
/// nor could you use [`send_ref`](Request::send_ref). /// payload nor could you use [`send_ref`](Request::send_ref).
/// ///
/// ## Examples /// ## Examples
/// ///
@ -74,7 +74,10 @@ macro_rules! fty {
}; };
} }
impl<B: Requester> Requester for AutoSend<B> { impl<B> Requester for AutoSend<B>
where
B: Requester,
{
type Err = B::Err; type Err = B::Err;
requester_forward! { requester_forward! {
@ -112,7 +115,10 @@ download_forward! {
#[pin_project::pin_project] #[pin_project::pin_project]
pub struct AutoRequest<R: Request>(#[pin] Inner<R>); pub struct AutoRequest<R: Request>(#[pin] Inner<R>);
impl<R: Request> AutoRequest<R> { impl<R> AutoRequest<R>
where
R: Request,
{
pub fn new(inner: R) -> Self { pub fn new(inner: R) -> Self {
Self(Inner::Request(inner)) Self(Inner::Request(inner))
} }
@ -133,7 +139,10 @@ enum Inner<R: Request> {
Done, Done,
} }
impl<R: Request> Request for AutoRequest<R> { impl<R> Request for AutoRequest<R>
where
R: Request,
{
type Err = R::Err; type Err = R::Err;
type Send = R::Send; type Send = R::Send;
type SendRef = R::SendRef; type SendRef = R::SendRef;

View file

@ -22,9 +22,41 @@ pub(crate) const TELOXIDE_PROXY: &str = "TELOXIDE_PROXY";
/// A requests sender. /// A requests sender.
/// ///
/// No need to put it into [`Arc`], because it's already in. /// This is the main type of the library, it allows to send requests to the
/// [Telegram Bot API] and download files.
///
/// ## TBA methods
///
/// All TBA methods are located in the [`Requester`] [`impl for Bot`]. This
/// allows for opt-in behaviours using requester [adaptors].
///
/// ```
/// # async {
/// use teloxide_core::prelude::*;
///
/// let bot = Bot::new("TOKEN");
/// dbg!(bot.get_me().send().await?);
/// # Ok::<_, teloxide_core::RequestError>(()) };
/// ```
///
/// [`Requester`]: crate::requests::Requester
/// [`impl for Bot`]: Bot#impl-Requester
/// [adaptors]: crate::adaptors
///
/// ## File download
///
/// In the similar way as with TBA methods, file downloading methods are located
/// in a trait — [`Download<'_>`]. See its documentation for more.
///
/// [`Download<'_>`]: crate::net::Download
///
/// ## Clone cost
///
/// `Bot::clone` is relatively cheap, so if you need to share `Bot`, it's
/// recommended to clone it, instead of wrapping it in [`Arc<_>`].
/// ///
/// [`Arc`]: std::sync::Arc /// [`Arc`]: std::sync::Arc
/// [Telegram Bot API]: https://core.telegram.org/bots/api
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Bot { pub struct Bot {
token: Arc<str>, token: Arc<str>,
@ -32,6 +64,7 @@ pub struct Bot {
client: Client, client: Client,
} }
/// Constructors
impl Bot { impl Bot {
/// Creates a new `Bot` with the specified token and the default /// Creates a new `Bot` with the specified token and the default
/// [http-client](reqwest::Client). /// [http-client](reqwest::Client).
@ -81,7 +114,7 @@ impl Bot {
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html /// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
/// [`reqwest::Proxy::all`]: https://docs.rs/reqwest/latest/reqwest/struct.Proxy.html#method.all /// [`reqwest::Proxy::all`]: https://docs.rs/reqwest/latest/reqwest/struct.Proxy.html#method.all
pub fn from_env() -> Self { pub fn from_env() -> Self {
Self::from_env_with_client(crate::client_from_env()) Self::from_env_with_client(crate::net::client_from_env())
} }
/// Creates a new `Bot` with the `TELOXIDE_TOKEN` environmental variable (a /// Creates a new `Bot` with the `TELOXIDE_TOKEN` environmental variable (a
@ -122,11 +155,31 @@ impl Bot {
/// bot.get_me().send().await /// bot.get_me().send().await
/// # }; /// # };
/// ``` /// ```
///
/// ## Multi-instance behaviour
///
/// This method only sets the url for one bot instace, older clones are
/// unaffected.
///
/// ```
/// use teloxide_core::Bot;
///
/// let bot = Bot::new("TOKEN");
/// let bot2 = bot.clone();
/// let bot = bot.set_api_url(reqwest::Url::parse("https://example.com/").unwrap());
///
/// assert_eq!(bot.api_url().as_str(), "https://example.com/");
/// assert_eq!(bot.clone().api_url().as_str(), "https://example.com/");
/// assert_ne!(bot2.api_url().as_str(), "https://example.com/");
/// ```
pub fn set_api_url(mut self, url: reqwest::Url) -> Self { pub fn set_api_url(mut self, url: reqwest::Url) -> Self {
self.api_url = ApiUrl::Custom(Arc::new(url)); self.api_url = ApiUrl::Custom(Arc::new(url));
self self
} }
}
/// Getters
impl Bot {
/// Returns currently used token. /// Returns currently used token.
pub fn token(&self) -> &str { pub fn token(&self) -> &str {
&self.token &self.token

View file

@ -53,7 +53,7 @@ pub enum RequestError {
#[error("An error while parsing JSON: {0}")] #[error("An error while parsing JSON: {0}")]
InvalidJson(#[source] serde_json::Error), InvalidJson(#[source] serde_json::Error),
// Occurs when trying to send a file to Telegram. /// Occurs when trying to send a file to Telegram.
#[error("An I/O error: {0}")] #[error("An I/O error: {0}")]
Io(#[source] io::Error), Io(#[source] io::Error),
} }

View file

@ -1,13 +1,69 @@
//! Core part of `teloxide` library. //! Core part of the [`teloxide`] library.
// TODO: expand docs //!
//! This library provides tools for making requests to the [Telegram Bot API]
//! (Currently, version `4.9` is supported) with ease. The library is fully
//! asynchronouns and built using [`tokio`].
//!
//!```toml
//! teloxide_core = "0.1"
//! ```
//! _Compiler support: requires rustc 1.49+_
//!
//! ```
//! # #[cfg(feature = "auto_send")]
//! # async {
//! # let chat_id = 0;
//! use teloxide_core::{
//! prelude::*,
//! types::{DiceEmoji, ParseMode},
//! };
//!
//! let bot = Bot::from_env()
//! .parse_mode(ParseMode::MarkdownV2)
//! .auto_send();
//!
//! let me = bot.get_me().await?;
//!
//! bot.send_dice(chat_id).emoji(DiceEmoji::Dice).await?;
//! bot.send_message(chat_id, format!("Hi, my name is **{}** 👋", me.first_name))
//! .await?;
//! # Ok::<_, Box<dyn std::error::Error>>(()) };
//! ```
//!
//! <div align="center">
//! <img src=https://user-images.githubusercontent.com/38225716/103929465-6b91e100-512e-11eb-826d-39b096f16548.gif />
//! </div>
//!
//! [`teloxide`]: https://docs.rs/teloxide
//! [Telegram Bot API]: https://core.telegram.org/bots/api
//! [`tokio`]: https://tokio.rs
//!
//! ## Cargo features
//!
//! - `auto_send` — enables [`AutoSend`] bot adaptor
//! - `throttle` — enables [`Throttle`] bot adaptor
//! - `cache_me` — enables [`CacheMe`] bot adaptor
//! - `full` — enables all features except `nigthly`
//! - `nightly` — enables nigthly-only features, currently:
//! - Removes some future boxing using `#![feature(type_alias_impl_trait)]`
//! - Used to built docs (`#![feature(doc_cfg, doc_spotlight)]`)
//!
//! [`AutoSend`]: adaptors::AutoSend
//! [`Throttle`]: adaptors::Throttle
//! [`CacheMe`]: adaptors::CacheMe
#![doc(
// FIXME(waffle): use github
html_logo_url = "https://cdn.discordapp.com/attachments/224881373326999553/798598120760934410/logo.png",
html_favicon_url = "https://cdn.discordapp.com/attachments/224881373326999553/798598120760934410/logo.png"
)]
#![forbid(unsafe_code)]
// we pass "--cfg docsrs" when building docs to add `This is supported on feature="..." only.` // we pass "--cfg docsrs" when building docs to add `This is supported on feature="..." only.`
// //
// To properly build docs of this crate run // To properly build docs of this crate run
// ```console // ```console
// $ RUSTDOCFLAGS="--cfg docsrs -Znormalize-docs" cargo doc --open --all-features // $ RUSTDOCFLAGS="--cfg docsrs -Znormalize-docs" cargo doc --open --all-features
// ``` // ```
#![forbid(unsafe_code)]
#![cfg_attr(all(docsrs, feature = "nightly"), feature(doc_cfg, doc_spotlight))] #![cfg_attr(all(docsrs, feature = "nightly"), feature(doc_cfg, doc_spotlight))]
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))] #![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
#![cfg_attr(feature = "full", deny(broken_intra_doc_links))] #![cfg_attr(feature = "full", deny(broken_intra_doc_links))]
@ -35,29 +91,3 @@ mod errors;
// implementation details // implementation details
mod serde_multipart; mod serde_multipart;
/// Constructs a client from the `TELOXIDE_PROXY` environmental variable.
///
/// This function passes the value of `TELOXIDE_PROXY` into
/// [`reqwest::Proxy::all`], if it exists, otherwise returns the default
/// client.
///
/// # Note
/// The created client will have safe settings, meaning that it will be able to
/// work in long time durations, see the [issue 223].
///
/// [`reqwest::Proxy::all`]: https://docs.rs/reqwest/latest/reqwest/struct.Proxy.html#method.all
/// [issue 223]: https://github.com/teloxide/teloxide/issues/223
pub fn client_from_env() -> reqwest::Client {
use crate::bot::{sound_bot, TELOXIDE_PROXY};
use reqwest::Proxy;
let builder = sound_bot();
match std::env::var(TELOXIDE_PROXY).ok() {
Some(proxy) => builder.proxy(Proxy::all(&proxy).expect("creating reqwest::Proxy")),
None => builder,
}
.build()
.expect("creating reqwest::Client")
}

View file

@ -47,7 +47,15 @@ macro_rules! req_future {
$(where $($wh:tt)*)? $(where $($wh:tt)*)?
) => { ) => {
#[pin_project::pin_project] #[pin_project::pin_project]
$v struct $i<$T> pub
// FIXME(waffle):
// The `pub` above should ideally be `$v`, but we currently can't do
// this due to compiler bug, see:
// - pin_project bug report <https://github.com/taiki-e/pin-project/issues/312>
// - related rustc issue <https://github.com/rust-lang/rust/issues/81007>
// - original fix (closed) <https://github.com/rust-lang/rust/pull/81029>
// - second iteration of the fix <https://github.com/rust-lang/rust/pull/81177>
struct $i<$T>
$(where $($wh)*)? $(where $($wh)*)?
{ {
#[pin] #[pin]
@ -188,6 +196,8 @@ macro_rules! impl_payload {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
// It's just easier for macros to generate such code. // It's just easier for macros to generate such code.
#[allow(clippy::redundant_field_names)] #[allow(clippy::redundant_field_names)]
// It's obvious what this method does. (If you think it's not, feel free to open a PR)
#[allow(missing_docs)]
$vi fn new($($($fields : impl_payload!(@convert? $FTy $([$conv])?)),*)?) -> Self { $vi fn new($($($fields : impl_payload!(@convert? $FTy $([$conv])?)),*)?) -> Self {
Self { Self {
$( $(

View file

@ -14,6 +14,38 @@ mod telegram_response;
/// The default Telegram API URL. /// The default Telegram API URL.
pub const TELEGRAM_API_URL: &str = "https://api.telegram.org"; pub const TELEGRAM_API_URL: &str = "https://api.telegram.org";
/// Constructs a network client from the `TELOXIDE_PROXY` environmental
/// variable.
///
/// This function passes the value of `TELOXIDE_PROXY` into
/// [`reqwest::Proxy::all`], if it exists, otherwise returns the default
/// client.
///
/// ## Note
///
/// The created client will have safe settings, meaning that it will be able to
/// work in long time durations, see the [issue 223].
///
/// [`reqwest::Proxy::all`]: https://docs.rs/reqwest/latest/reqwest/struct.Proxy.html#method.all
/// [issue 223]: https://github.com/teloxide/teloxide/issues/223
///
/// ## Panics
///
/// If `TELOXIDE_PROXY` exists, but isn't correct url.
pub fn client_from_env() -> reqwest::Client {
use crate::bot::{sound_bot, TELOXIDE_PROXY};
use reqwest::Proxy;
let builder = sound_bot();
match std::env::var(TELOXIDE_PROXY).ok() {
Some(proxy) => builder.proxy(Proxy::all(&proxy).expect("creating reqwest::Proxy")),
None => builder,
}
.build()
.expect("creating reqwest::Client")
}
/// Creates URL for making HTTPS requests. See the [Telegram documentation]. /// Creates URL for making HTTPS requests. See the [Telegram documentation].
/// ///
/// [Telegram documentation]: https://core.telegram.org/bots/api#making-requests /// [Telegram documentation]: https://core.telegram.org/bots/api#making-requests

View file

@ -1,7 +1,8 @@
//! Request data sent to Telegram. //! Request data sent to Telegram.
/// This module re-exports all the setters traits as `_`. When used with a glob /// This module re-exports all the setters traits as `_`.
/// import: ///
/// When used with a glob import:
/// ///
/// ``` /// ```
/// use teloxide_core::payloads::setters::*; /// use teloxide_core::payloads::setters::*;

View file

@ -1,3 +1,7 @@
//! Commonly used items. //! Commonly used items.
pub use crate::requests::Requester; pub use crate::{
payloads::setters::*,
requests::{Request, Requester, RequesterExt},
Bot,
};

View file

@ -13,7 +13,7 @@ use crate::requests::{HasPayload, Output};
/// ///
/// This is crucial for request wrappers which may want to cancel and/or never /// This is crucial for request wrappers which may want to cancel and/or never
/// send the underlying request. E.g.: [`Throttle<B>`]'s `send_ref` calls /// send the underlying request. E.g.: [`Throttle<B>`]'s `send_ref` calls
/// `B::send_ref` while _not_ meaning to really send the request right now. /// `B::send_ref` while _not_ meaning to really send the request at the moment.
/// ///
/// [`Throttle<B>`]: crate::adaptors::Throttle /// [`Throttle<B>`]: crate::adaptors::Throttle
#[cfg_attr(all(docsrs, feature = "nightly"), doc(spotlight))] #[cfg_attr(all(docsrs, feature = "nightly"), doc(spotlight))]
@ -32,8 +32,8 @@ pub trait Request: HasPayload {
/// A type of the future returned by the [`send_ref`](Request::send_ref) /// A type of the future returned by the [`send_ref`](Request::send_ref)
/// method. /// method.
// Note: it intentionally forbids borrowing from `self` though anyway we // Note: it intentionally forbids borrowing from `self` though we couldn't allow
// couldn't allow borrowing without GATs. // borrowing without GATs anyway.
type SendRef: Future<Output = Result<Output<Self>, Self::Err>> + Send; type SendRef: Future<Output = Result<Output<Self>, Self::Err>> + Send;
/// Send this request. /// Send this request.
@ -49,6 +49,8 @@ pub trait Request: HasPayload {
/// }; /// };
/// ///
/// let bot = Bot::new("TOKEN"); /// let bot = Bot::new("TOKEN");
///
/// // Note: it's recommended to `Requester` instead of creating requests directly
/// let method = GetMe::new(); /// let method = GetMe::new();
/// let request = JsonRequest::new(bot, method); /// let request = JsonRequest::new(bot, method);
/// let _: User = request.send().await.unwrap(); /// let _: User = request.send().await.unwrap();

View file

@ -15,9 +15,42 @@ use crate::{
/// ///
/// This trait is implemented by all bots & bot adaptors. /// This trait is implemented by all bots & bot adaptors.
/// ///
/// _This trait is included in the crate's [`prelude`](crate::prelude)_. /// ## Examples
///
/// Calling TBA methods:
///
/// ```
/// # async {
/// use teloxide_core::{prelude::*, types::ParseMode};
///
/// // Bot implements `Requester`
/// let bot = Bot::new("TOKEN");
///
/// // Required parameters are supplied to the `Requester` methods:
/// bot.send_message(0, "<b>Text</b>")
/// // Optional parameters can be supplied by calling setters
/// .parse_mode(ParseMode::HTML)
/// // To send request to telegram you need to call `.send()` and await the resulting future
/// .send()
/// .await?;
/// # Ok::<_, teloxide_core::RequestError>(()) };
/// ```
///
/// Using `Requester` in a generic context:
///
/// ```
/// use teloxide_core::{prelude::*, types::Message};
///
/// async fn send_hi<R>(bot: R, chat: i64) -> Message
/// where
/// R: Requester,
/// {
/// bot.send_message(chat, "hi").send().await.expect("error")
/// }
/// ```
#[cfg_attr(all(docsrs, feature = "nightly"), doc(spotlight))] #[cfg_attr(all(docsrs, feature = "nightly"), doc(spotlight))]
pub trait Requester { pub trait Requester {
/// Error type returned by all requests.
type Err: std::error::Error + Send; type Err: std::error::Error + Send;
// This block is auto generated by `cg` <https://github.com/teloxide/cg> (be02d84). // This block is auto generated by `cg` <https://github.com/teloxide/cg> (be02d84).

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

@ -1,254 +1,504 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// ISO 3166-1 alpha-2 language code.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum CountryCode { pub enum CountryCode {
/// Andorra
AD, AD,
/// United Arab Emirates
AE, AE,
/// Afghanistan
AF, AF,
/// Antigua and Barbuda
AG, AG,
/// Anguilla
AI, AI,
/// Albania
AL, AL,
/// Armenia
AM, AM,
/// Angola
AO, AO,
/// Antarctica
AQ, AQ,
/// Argentina
AR, AR,
/// American Samoa
AS, AS,
/// Austria
AT, AT,
/// Australia
AU, AU,
/// Aruba
AW, AW,
/// Åland Islands
AX, AX,
/// Azerbaijan
AZ, AZ,
/// Bosnia and Herzegovina
BA, BA,
/// Barbados
BB, BB,
/// Bangladesh
BD, BD,
/// Belgium
BE, BE,
/// Burkina Faso
BF, BF,
/// Bulgaria
BG, BG,
/// Bahrain
BH, BH,
/// Burundi
BI, BI,
/// Benin
BJ, BJ,
/// Saint Barthélemy
BL, BL,
/// Bermuda
BM, BM,
/// Brunei Darussalam
BN, BN,
/// Bolivia (Plurinational State of)
BO, BO,
/// Bonaire, Sint Eustatius and Saba
BQ, BQ,
/// Brazil
BR, BR,
/// Bahamas
BS, BS,
/// Bhutan
BT, BT,
/// Bouvet Island
BV, BV,
/// Botswana
BW, BW,
/// Belarus
BY, BY,
/// Belize
BZ, BZ,
/// Canada
CA, CA,
/// Cocos (Keeling) Islands
CC, CC,
/// Congo, Democratic Republic of the
CD, CD,
/// Central African Republic
CF, CF,
/// Congo
CG, CG,
/// Switzerland
CH, CH,
/// Côte d'Ivoire
CI, CI,
/// Cook Islands
CK, CK,
/// Chile
CL, CL,
/// Cameroon
CM, CM,
/// China
CN, CN,
/// Colombia
CO, CO,
/// Costa Rica
CR, CR,
/// Cuba
CU, CU,
/// Cabo Verde
CV, CV,
/// Curaçao
CW, CW,
/// Christmas Island
CX, CX,
/// Cyprus
CY, CY,
/// Czechia
CZ, CZ,
/// Germany
DE, DE,
/// Djibouti
DJ, DJ,
/// Denmark
DK, DK,
/// Dominica
DM, DM,
/// Dominican Republic
DO, DO,
/// Algeria
DZ, DZ,
/// Ecuador
EC, EC,
/// Estonia
EE, EE,
/// Egypt
EG, EG,
/// Western Sahara
EH, EH,
/// Eritrea
ER, ER,
/// Spain
ES, ES,
/// Ethiopia
ET, ET,
/// Finland
FI, FI,
/// Fiji
FJ, FJ,
/// Falkland Islands (Malvinas)
FK, FK,
/// Micronesia (Federated States of)
FM, FM,
/// Faroe Islands
FO, FO,
/// France
FR, FR,
/// Gabon
GA, GA,
/// United Kingdom of Great Britain and Northern Ireland
GB, GB,
/// Grenada
GD, GD,
/// Georgia
GE, GE,
/// French Guiana
GF, GF,
/// Guernsey
GG, GG,
/// Ghana
GH, GH,
/// Gibraltar
GI, GI,
/// Greenland
GL, GL,
/// Gambia
GM, GM,
/// Guinea
GN, GN,
/// Guadeloupe
GP, GP,
/// Equatorial Guinea
GQ, GQ,
/// Greece
GR, GR,
/// South Georgia and the South Sandwich Islands
GS, GS,
/// Guatemala
GT, GT,
/// Guam
GU, GU,
/// Guinea-Bissau
GW, GW,
/// Guyana
GY, GY,
/// Hong Kong
HK, HK,
/// Heard Island and McDonald Islands
HM, HM,
/// Honduras
HN, HN,
/// Croatia
HR, HR,
/// Haiti
HT, HT,
/// Hungary
HU, HU,
/// Indonesia
ID, ID,
/// Ireland
IE, IE,
/// Israel
IL, IL,
/// Isle of Man
IM, IM,
/// India
IN, IN,
/// British Indian Ocean Territory
IO, IO,
/// Iraq
IQ, IQ,
/// Iran (Islamic Republic of)
IR, IR,
/// Iceland
IS, IS,
/// Italy
IT, IT,
/// Jersey
JE, JE,
/// Jamaica
JM, JM,
/// Jordan
JO, JO,
/// Japan
JP, JP,
/// Kenya
KE, KE,
/// Kyrgyzstan
KG, KG,
/// Cambodia
KH, KH,
/// Kiribati
KI, KI,
/// Comoros
KM, KM,
/// Saint Kitts and Nevis
KN, KN,
/// Korea (Democratic People's Republic of)
KP, KP,
/// Korea, Republic of
KR, KR,
/// Kuwait
KW, KW,
/// Cayman Islands
KY, KY,
/// Kazakhstan
KZ, KZ,
/// Lao People's Democratic Republic
LA, LA,
/// Lebanon
LB, LB,
/// Saint Lucia
LC, LC,
/// Liechtenstein
LI, LI,
/// Sri Lanka
LK, LK,
/// Liberia
LR, LR,
/// Lesotho
LS, LS,
/// Lithuania
LT, LT,
/// Luxembourg
LU, LU,
/// Latvia
LV, LV,
/// Libya
LY, LY,
/// Morocco
MA, MA,
/// Monaco
MC, MC,
/// Moldova, Republic of
MD, MD,
/// Montenegro
ME, ME,
/// Saint Martin (French part)
MF, MF,
/// Madagascar
MG, MG,
/// Marshall Islands
MH, MH,
/// North Macedonia
MK, MK,
/// Mali
ML, ML,
/// Myanmar
MM, MM,
/// Mongolia
MN, MN,
/// Macao
MO, MO,
/// Northern Mariana Islands
MP, MP,
/// Martinique
MQ, MQ,
/// Mauritania
MR, MR,
/// Montserrat
MS, MS,
/// Malta
MT, MT,
/// Mauritius
MU, MU,
/// Maldives
MV, MV,
/// Malawi
MW, MW,
/// Mexico
MX, MX,
/// Malaysia
MY, MY,
/// Mozambique
MZ, MZ,
/// Namibia
NA, NA,
/// New Caledonia
NC, NC,
/// Niger
NE, NE,
/// Norfolk Island
NF, NF,
/// Nigeria
NG, NG,
/// Nicaragua
NI, NI,
/// Netherlands
NL, NL,
/// Norway
NO, NO,
/// Nepal
NP, NP,
/// Nauru
NR, NR,
/// Niue
NU, NU,
/// New Zealand
NZ, NZ,
/// Oman
OM, OM,
/// Panama
PA, PA,
/// Peru
PE, PE,
/// French Polynesia
PF, PF,
/// Papua New Guinea
PG, PG,
/// Philippines
PH, PH,
/// Pakistan
PK, PK,
/// Poland
PL, PL,
/// Saint Pierre and Miquelon
PM, PM,
/// Pitcairn
PN, PN,
/// Puerto Rico
PR, PR,
/// Palestine, State of
PS, PS,
/// Portugal
PT, PT,
/// Palau
PW, PW,
/// Paraguay
PY, PY,
/// Qatar
QA, QA,
/// Réunion
RE, RE,
/// Romania
RO, RO,
/// Serbia
RS, RS,
/// Russian Federation
RU, RU,
/// Rwanda
RW, RW,
/// Saudi Arabia
SA, SA,
/// Solomon Islands
SB, SB,
/// Seychelles
SC, SC,
/// Sudan
SD, SD,
/// Sweden
SE, SE,
/// Singapore
SG, SG,
/// Saint Helena, Ascension and Tristan da Cunha
SH, SH,
/// Slovenia
SI, SI,
/// Svalbard and Jan Mayen
SJ, SJ,
/// Slovakia
SK, SK,
/// Sierra Leone
SL, SL,
/// San Marino
SM, SM,
/// Senegal
SN, SN,
/// Somalia
SO, SO,
/// Suriname
SR, SR,
/// South Sudan
SS, SS,
/// Sao Tome and Principe
ST, ST,
/// El Salvador
SV, SV,
/// Sint Maarten (Dutch part)
SX, SX,
/// Syrian Arab Republic
SY, SY,
/// Eswatini
SZ, SZ,
/// Turks and Caicos Islands
TC, TC,
/// Chad
TD, TD,
/// French Southern Territories
TF, TF,
/// Togo
TG, TG,
/// Thailand
TH, TH,
/// Tajikistan
TJ, TJ,
/// Tokelau
TK, TK,
/// Timor-Leste
TL, TL,
/// Turkmenistan
TM, TM,
/// Tunisia
TN, TN,
/// Tonga
TO, TO,
/// Turkey
TR, TR,
/// Trinidad and Tobago
TT, TT,
/// Tuvalu
TV, TV,
/// Taiwan, Province of China
TW, TW,
/// Tanzania, United Republic of
TZ, TZ,
/// Ukraine
UA, UA,
/// Uganda
UG, UG,
/// United States Minor Outlying Islands
UM, UM,
/// United States of America
US, US,
/// Uruguay
UY, UY,
/// Uzbekistan
UZ, UZ,
/// Holy See
VA, VA,
/// Saint Vincent and the Grenadines
VC, VC,
/// Venezuela (Bolivarian Republic of)
VE, VE,
/// Virgin Islands (British)
VG, VG,
/// Virgin Islands (U.S.)
VI, VI,
/// Viet Nam
VN, VN,
/// Vanuatu
VU, VU,
/// Wallis and Futuna
WF, WF,
/// Samoa
WS, WS,
/// Yemen
YE, YE,
/// Mayotte
YT, YT,
/// South Africa
ZA, ZA,
/// Zambia
ZM, ZM,
/// Zimbabwe
ZW, ZW,
} }

View file

@ -1,89 +1,364 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// ISO 4217 currency.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum Currency { pub enum Currency {
/// United Arab Emirates dirham
AED, AED,
/// Afghan afghani
AFN, AFN,
/// Albanian lek
ALL, ALL,
/// Armenian dram
AMD, AMD,
/// Netherlands Antillean guilder
ANG,
/// Angolan kwanza
AOA,
/// Argentine peso
ARS, ARS,
/// Australian dollar
AUD, AUD,
/// Aruban florin
AWG,
/// Azerbaijani manat
AZN, AZN,
/// Bosnia and Herzegovina convertible mark
BAM, BAM,
/// Barbados dollar
BBD,
/// Bangladeshi taka
BDT, BDT,
/// Bulgarian lev
BGN, BGN,
/// Bahraini dinar
BHD,
/// Burundian franc
BIF,
/// Bermudian dollar
BMD,
/// Brunei dollar
BND, BND,
/// Boliviano
BOB, BOB,
/// Bolivian Mvdol (funds code)
BOV,
/// Brazilian real
BRL, BRL,
/// Bahamian dollar
BSD,
/// Bhutanese ngultrum
BTN,
/// Botswana pula
BWP,
/// Belarusian ruble
BYN,
/// Belize dollar
BZD,
/// Canadian dollar
CAD, CAD,
/// Congolese franc
CDF,
/// WIR euro (complementary currency)
CHE,
/// Swiss franc
CHF, CHF,
/// WIR franc (complementary currency)
CHW,
/// Unidad de Fomento (funds code)
CLF,
/// Chilean peso
CLP, CLP,
/// Chinese yuan
CNY, CNY,
/// Colombian peso
COP, COP,
/// Unidad de Valor Real (UVR) (funds code)
COU,
/// Costa Rican colon
CRC, CRC,
/// Cuban convertible peso
CUC,
/// Cuban peso
CUP,
/// Cape Verdean escudo
CVE,
/// Czech koruna
CZK, CZK,
/// Djiboutian franc
DJF,
/// Danish krone
DKK, DKK,
/// Dominican peso
DOP, DOP,
/// Algerian dinar
DZD, DZD,
/// Egyptian pound
EGP, EGP,
/// Eritrean nakfa
ERN,
/// Ethiopian birr
ETB,
/// Euro
EUR, EUR,
/// Fiji dollar
FJD,
/// Falkland Islands pound
FKP,
/// Pound sterling
GBP, GBP,
/// Georgian lari
GEL, GEL,
/// Ghanaian cedi
GHS,
/// Gibraltar pound
GIP,
/// Gambian dalasi
GMD,
/// Guinean franc
GNF,
/// Guatemalan quetzal
GTQ, GTQ,
/// Guyanese dollar
GYD,
/// Hong Kong dollar
HKD, HKD,
/// Honduran lempira
HNL, HNL,
/// Croatian kuna
HRK, HRK,
/// Haitian gourde
HTG,
/// Hungarian forint
HUF, HUF,
/// Indonesian rupiah
IDR, IDR,
/// Israeli new shekel
ILS, ILS,
/// Indian rupee
INR, INR,
/// Iraqi dinar
IQD,
/// Iranian rial
IRR,
/// Icelandic króna
ISK, ISK,
/// Jamaican dollar
JMD, JMD,
/// Jordanian dinar
JOD,
/// Japanese yen
JPY, JPY,
/// Kenyan shilling
KES, KES,
/// Kyrgyzstani som
KGS, KGS,
/// Cambodian riel
KHR,
/// Comoro franc
KMF,
/// North Korean won
KPW,
/// South Korean won
KRW, KRW,
/// Kuwaiti dinar
KWD,
/// Cayman Islands dollar
KYD,
/// Kazakhstani tenge
KZT, KZT,
/// Lao kip
LAK,
/// Lebanese pound
LBP, LBP,
/// Sri Lankan rupee
LKR, LKR,
/// Liberian dollar
LRD,
/// Lesotho loti
LSL,
/// Libyan dinar
LYD,
/// Moroccan dirham
MAD, MAD,
/// Moldovan leu
MDL, MDL,
/// Malagasy ariary
MGA,
/// Macedonian denar
MKD,
/// Myanmar kyat
MMK,
/// Mongolian tögrög
MNT, MNT,
/// Macanese pataca
MOP,
/// Mauritanian ouguiya
MRU,
/// Mauritian rupee
MUR, MUR,
/// Maldivian rufiyaa
MVR, MVR,
/// Malawian kwacha
MWK,
/// Mexican peso
MXN, MXN,
/// Mexican Unidad de Inversion (UDI) (funds code)
MXV,
/// Malaysian ringgit
MYR, MYR,
/// Mozambican metical
MZN, MZN,
/// Namibian dollar
NAD,
/// Nigerian naira
NGN, NGN,
/// Nicaraguan córdoba
NIO, NIO,
/// Norwegian krone
NOK, NOK,
/// Nepalese rupee
NPR, NPR,
/// New Zealand dollar
NZD, NZD,
/// Omani rial
OMR,
/// Panamanian balboa
PAB, PAB,
/// Peruvian sol
PEN, PEN,
/// Papua New Guinean kina
PGK,
/// Philippine peso
PHP, PHP,
/// Pakistani rupee
PKR, PKR,
/// Polish złoty
PLN, PLN,
/// Paraguayan guaraní
PYG, PYG,
/// Qatari riyal
QAR, QAR,
/// Romanian leu
RON, RON,
/// Serbian dinar
RSD, RSD,
/// Russian ruble
RUB, RUB,
/// Rwandan franc
RWF,
/// Saudi riyal
SAR, SAR,
/// Solomon Islands dollar
SBD,
/// Seychelles rupee
SCR,
/// Sudanese pound
SDG,
/// Swedish krona/kronor
SEK, SEK,
/// Singapore dollar
SGD, SGD,
/// Saint Helena pound
SHP,
/// Sierra Leonean leone
SLL,
/// Somali shilling
SOS,
/// Surinamese dollar
SRD,
/// South Sudanese pound
SSP,
/// São Tomé and Príncipe dobra
STN,
/// Salvadoran colón
SVC,
/// Syrian pound
SYP,
/// Swazi lilangeni
SZL,
/// Thai baht
THB, THB,
/// Tajikistani somoni
TJS, TJS,
/// Turkmenistan manat
TMT,
/// Tunisian dinar
TND,
/// Tongan paʻanga
TOP,
/// Turkish lira
TRY, TRY,
/// Trinidad and Tobago dollar
TTD, TTD,
/// New Taiwan dollar
TWD, TWD,
/// Tanzanian shilling
TZS, TZS,
/// Ukrainian hryvnia
UAH, UAH,
/// Ugandan shilling
UGX, UGX,
/// United States dollar
USD, USD,
/// United States dollar (next day) (funds code)
USN,
/// Uruguay Peso en Unidades Indexadas (URUIURUI) (funds code)
UYI,
/// Uruguayan peso
UYU, UYU,
/// Unidad previsional
UYW,
/// Uzbekistan som
UZS, UZS,
/// Venezuelan bolívar soberano
VES,
/// Vietnamese đồng
VND, VND,
/// Vanuatu vatu
VUV,
/// Samoan tala
WST,
/// CFA franc BEAC
XAF,
/// Silver (one troy ounce)
XAG,
/// Gold (one troy ounce)
XAU,
/// European Composite Unit (EURCO) (bond market unit)
XBA,
/// European Monetary Unit (E.M.U.-6) (bond market unit)
XBB,
/// European Unit of Account 9 (E.U.A.-9) (bond market unit)
XBC,
/// European Unit of Account 17 (E.U.A.-17) (bond market unit)
XBD,
/// East Caribbean dollar
XCD,
/// Special drawing rights
XDR,
/// CFA franc BCEAO
XOF,
/// Palladium (one troy ounce)
XPD,
/// CFP franc (franc Pacifique)
XPF,
/// Platinum (one troy ounce)
XPT,
/// SUCRE
XSU,
/// Code reserved for testing
XTS,
/// ADB Unit of Account
XUA,
/// No currency
XXX,
/// Yemeni rial
YER, YER,
/// South African rand
ZAR, ZAR,
/// Zambian kwacha
ZMW,
/// Zimbabwean dollar
ZWL,
} }

View file

@ -0,0 +1,97 @@
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<(), 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
} }