mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-24 09:16:12 +01:00
commit
8e011b7e60
29 changed files with 2853 additions and 116 deletions
|
@ -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"]
|
||||||
|
|
25
README.md
25
README.md
|
@ -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
23
examples/self_info.rs
Normal 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
BIN
media/example.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
BIN
media/logo.png
Normal file
BIN
media/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
1907
media/logo.svg
Normal file
1907
media/logo.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 61 KiB |
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
88
src/lib.rs
88
src/lib.rs
|
@ -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")
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 {
|
||||||
$(
|
$(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
97
src/types/non_telegram_types/mime.rs
Normal file
97
src/types/non_telegram_types/mime.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue