Merge pull request #117 from teloxide/until_date_fixes

`until_date` fixes
This commit is contained in:
Hirrolot 2021-09-03 20:49:29 -07:00 committed by GitHub
commit 4986f72ef4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 11 deletions

View file

@ -7,12 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased]
- Add `EditedMessageIsTooLong` error [#109][pr109]
- Use `url::Url` for urls, use `chrono::DateTime<Utc>` for dates in types ([#115][pr115])
### Added
- `EditedMessageIsTooLong` error [#109][pr109]
- `UntilDate` enum and use it for `{Restricted, Banned}::until_date` ([#116][pr116])
[pr109]: https://github.com/teloxide/teloxide-core/pull/109
[pr116]: https://github.com/teloxide/teloxide-core/pull/116
### Changed
- Use `url::Url` for urls, use `chrono::DateTime<Utc>` for dates in types ([#115][pr115])
[pr115]: https://github.com/teloxide/teloxide-core/pull/115
### Fixed
- Type of `BanChatMember::until_date`: `u64` -> `chrono::DateTime<Utc>` ([#116][pr116])
## 0.3.3
### Fixed

View file

@ -6,6 +6,7 @@
//
// [cg]: https://github.com/teloxide/cg
// [`schema`]: https://github.com/WaffleLapkin/tg-methods-schema
use chrono::{DateTime, Utc};
use serde::Serialize;
use crate::types::{ChatId, True};
@ -24,7 +25,8 @@ impl_payload! {
}
optional {
/// Date when the user will be unbanned, unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever
pub until_date: u64,
#[serde(with = "crate::types::serde_opt_date_from_unix_timestamp")]
pub until_date: DateTime<Utc> [into],
/// Pass True to delete all messages from the chat for the user that is being removed. If False, the user will be able to see messages in the group that were sent before the user was removed. Always True for supergroups and channels.
pub revoke_messages: bool,
}

View file

@ -212,12 +212,13 @@ mod passport_data;
mod passport_element_error;
mod passport_file;
pub use non_telegram_types::{country_code::*, currency::*, semiparsed_vec::*};
pub use non_telegram_types::{country_code::*, currency::*, semiparsed_vec::*, until_date::*};
mod non_telegram_types {
pub(super) mod country_code;
pub(super) mod currency;
pub(crate) mod mime;
pub(super) mod semiparsed_vec;
pub(super) mod until_date;
}
pub(crate) mod serde_opt_date_from_unix_timestamp {

View file

@ -1,9 +1,8 @@
use std::ops::Deref;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::types::User;
use crate::types::{UntilDate, User};
/// This object contains information about one member of the chat.
///
@ -100,8 +99,7 @@ pub struct Administrator {
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Restricted {
/// Date when restrictions will be lifted for this user.
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub until_date: DateTime<Utc>,
pub until_date: UntilDate,
/// `true` if the user can send text messages, contacts, locations and
/// venues.
@ -125,8 +123,7 @@ pub struct Restricted {
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Banned {
/// Date when restrictions will be lifted for this user.
#[serde(with = "crate::types::serde_date_from_unix_timestamp")]
pub until_date: DateTime<Utc>,
pub until_date: UntilDate,
}
/// This allows calling [`ChatMemberKind`]'s methods directly on [`ChatMember`].
@ -273,7 +270,7 @@ impl ChatMemberKind {
}
/// Getter for [`Restricted::until_date`] and [`Banned::until_date`] fields.
pub fn until_date(&self) -> Option<DateTime<Utc>> {
pub fn until_date(&self) -> Option<UntilDate> {
match &self {
Self::Owner(_) | Self::Administrator(_) | Self::Member | Self::Left => None,
Self::Restricted(Restricted { until_date, .. })

View file

@ -0,0 +1,56 @@
use chrono::{DateTime, NaiveDateTime, Utc};
use serde::{de::Visitor, Deserialize, Serialize};
/// A range of time, before some date (for example a time before a restrictions
/// will be lifted from a member of a chat).
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum UntilDate {
/// The range is bound by a given date and time.
Date(DateTime<Utc>),
/// There is no end date, the range is unbounded.
Forever,
}
impl<'de> Deserialize<'de> for UntilDate {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct UntilDateVisitor;
impl<'v> Visitor<'v> for UntilDateVisitor {
type Value = UntilDate;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an integer representing a UNIX timestamp or a 0")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match v {
0 => Ok(UntilDate::Forever),
timestamp => Ok(UntilDate::Date(DateTime::from_utc(
NaiveDateTime::from_timestamp(timestamp, 0),
Utc,
))),
}
}
}
deserializer.deserialize_i64(UntilDateVisitor)
}
}
impl Serialize for UntilDate {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_i64(match self {
UntilDate::Date(dt) => dt.timestamp(),
UntilDate::Forever => 0,
})
}
}