From 851722e46cbb02c31640a0c8a1e0433de195f38a Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 2 Jun 2022 20:46:41 +0400 Subject: [PATCH] Fix deserialization of `File` when `file_path` or `file_size` are missing --- CHANGELOG.md | 2 ++ src/types/file.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe2e1c0a..692d9e1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +- Fix deserialization of `File` when `file_path` or `file_size` are missing ([#220][pr220]) - Add `ChatId` and `UserId` to the prelude ([#212][pr212]) - Add `is_*` methods to `ChatMemberStatus` analogous to the `ChatMember{,Kind}` methods ([#216][pr216]) +[pr220]: https://github.com/teloxide/teloxide-core/pull/220 [pr212]: https://github.com/teloxide/teloxide-core/pull/212 [pr216]: https://github.com/teloxide/teloxide-core/pull/216 diff --git a/src/types/file.rs b/src/types/file.rs index 82aa237e..05402ffa 100644 --- a/src/types/file.rs +++ b/src/types/file.rs @@ -22,11 +22,62 @@ pub struct File { pub file_unique_id: String, /// File size, if known. + /// + /// **Note:** in the Telegram Bot API this field is optional, however it was + /// errourneusly marked as required in Teloxide. To workaround this issue, + /// when `file_size` is not present, it is deserialized as [`u32::MAX`]. + #[serde(default = "default_file_size")] pub file_size: u32, /// File path. Use [`Bot::download_file(file_path, dst)`] to get the file. /// - /// [`Bot::download_file(file_path, dst)`]: - /// crate::net::Download::download_file + /// **Note:** in the Telegram Bot API this field is optional, however it was + /// errourneusly marked as required in Teloxide. To workaround this issue, + /// when `file_path` is not present, it is deserialized as an empty string. + /// + /// [`Bot::download_file(file_path, dst)`]: crate::net::Download::download_file + #[serde(default)] pub file_path: String, } + +const fn default_file_size() -> u32 { + u32::MAX +} + +#[cfg(test)] +mod tests { + use crate::types::File; + + #[test] + fn no_file_size() { + let json = + r#"{"file_id":"FILE_ID","file_unique_id":"FILE_UNIQUE_ID","file_path":"FILE_PATH"}"#; + let file: File = serde_json::from_str(json).unwrap(); + + assert_eq!( + file, + File { + file_id: "FILE_ID".to_owned(), + file_unique_id: "FILE_UNIQUE_ID".to_owned(), + file_size: u32::MAX, + file_path: "FILE_PATH".to_owned(), + } + ); + } + + #[test] + fn no_file_path() { + let json = r#"{"file_id":"FILE_ID","file_unique_id":"FILE_UNIQUE_ID","file_size":42}"#; + let file: File = serde_json::from_str(json).unwrap(); + + assert_eq!( + file, + File { + file_id: "FILE_ID".to_owned(), + file_unique_id: "FILE_UNIQUE_ID".to_owned(), + file_size: 42, + file_path: "".to_owned(), + } + ); + } +}