From 63acd976e7b90567f1555c3f7defaed35c1a3ba1 Mon Sep 17 00:00:00 2001 From: StNicolay Date: Thu, 20 Jul 2023 23:28:26 +0300 Subject: [PATCH] Moved document validation into a sepparate func --- src/state/get_user.rs | 57 +++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/state/get_user.rs b/src/state/get_user.rs index 4c24187..a7e316e 100644 --- a/src/state/get_user.rs +++ b/src/state/get_user.rs @@ -2,15 +2,36 @@ use crate::prelude::*; use futures::future::try_join; use itertools::Itertools; use rustc_hash::FxHashSet; -use std::fmt::Write; -use teloxide::{net::Download, types::Document}; +use std::{fmt::Write, path::Path}; +use teloxide::{ + net::Download, + types::{Document, FileMeta}, +}; use tokio::task::spawn_blocking; use trim_in_place::TrimInPlace; #[inline] -async fn download_file(bot: &Throttle, document: &Document) -> crate::Result> { - let path = bot.get_file(document.file.id.as_str()).await?.path; - let mut data = Vec::with_capacity(document.file.size as usize); +fn validate_document(document: Option<&Document>) -> Result<&Document, &'static str> { + let document = match document { + Some(document) => document, + None => return Err("You didn't send a file. Try again"), + }; + + let name = match document.file_name.as_deref() { + Some(name) => Path::new(name.trim_end()), + None => return Err("Couldn't get the name of the file. Try sending it again"), + }; + + match name.extension() { + Some(ext) if ext.eq_ignore_ascii_case("json") => Ok(document), + _ => Err("Invalid file name. You need to send a json file. Try again"), + } +} + +#[inline] +async fn download_file(bot: &Throttle, file: &FileMeta) -> crate::Result> { + let path = bot.get_file(file.id.as_str()).await?.path; + let mut data = Vec::with_capacity(file.size as usize); bot.download_file_stream(&path) .try_for_each(|bytes| { data.extend(bytes); @@ -131,31 +152,15 @@ pub async fn get_user( return Ok(()); } - let document = match msg.document() { - Some(document) => document, - None => { - let msg = bot - .send_message(msg.chat.id, "You didn't send a file. Try again") - .await?; + let file = match validate_document(msg.document()) { + Ok(document) => &document.file, + Err(text) => { + let msg = bot.send_message(msg.chat.id, text).await?; handler.previous = MessageIds::from(&msg); return Ok(()); } }; - match document.file_name.as_deref() { - Some(name) if name.trim_end().ends_with(".json") => (), - _ => { - let msg = bot - .send_message( - msg.chat.id, - "Invalid file name. You need to send a json file. Try again", - ) - .await?; - handler.previous = MessageIds::from(&msg); - return Ok(()); - } - } - let existing_names = async { Account::get_names(user_id, &db) .await? @@ -164,7 +169,7 @@ pub async fn get_user( .map_err(Into::into) }; - let (data, existing_names) = try_join(download_file(&bot, document), existing_names).await?; + let (data, existing_names) = try_join(download_file(&bot, file), existing_names).await?; let user = match spawn_blocking(move || user_from_vec(data, existing_names)).await? { Ok(Ok(user)) => user,