cargo fmt
This commit is contained in:
		
							parent
							
								
									9ca4dda9d9
								
							
						
					
					
						commit
						c2ea9b87b0
					
				
							
								
								
									
										17
									
								
								src/api.rs
								
								
								
								
							
							
						
						
									
										17
									
								
								src/api.rs
								
								
								
								
							| 
						 | 
				
			
			@ -2,18 +2,23 @@ use crate::structs;
 | 
			
		|||
 | 
			
		||||
extern crate serde_json;
 | 
			
		||||
 | 
			
		||||
pub async fn get_sauce_info(client: reqwest::Client, sauce: i32) -> Result<structs::GalleryInfo, reqwest::Error> {
 | 
			
		||||
pub async fn get_sauce_info(
 | 
			
		||||
    client: reqwest::Client,
 | 
			
		||||
    sauce: i32,
 | 
			
		||||
) -> Result<structs::GalleryInfo, reqwest::Error> {
 | 
			
		||||
    let mut uri = String::from("https://nhentai.net/api/gallery/");
 | 
			
		||||
    uri.push_str(&sauce.to_string());
 | 
			
		||||
    let resp = client.get(&uri)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await?;
 | 
			
		||||
    let resp = client.get(&uri).send().await?;
 | 
			
		||||
    Ok(serde_json::from_str(&resp.text().await?).unwrap())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn get_search_info(client: reqwest::Client, search_query: &str) -> Result<structs::SearchInfo, reqwest::Error> {
 | 
			
		||||
pub async fn get_search_info(
 | 
			
		||||
    client: reqwest::Client,
 | 
			
		||||
    search_query: &str,
 | 
			
		||||
) -> Result<structs::SearchInfo, reqwest::Error> {
 | 
			
		||||
    let uri = "https://nhentai.net/api/galleries/search";
 | 
			
		||||
    let resp = client.get(uri)
 | 
			
		||||
    let resp = client
 | 
			
		||||
        .get(uri)
 | 
			
		||||
        .query(&[("query", search_query)])
 | 
			
		||||
        .send()
 | 
			
		||||
        .await?;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
mod view;
 | 
			
		||||
mod search;
 | 
			
		||||
mod download;
 | 
			
		||||
mod search;
 | 
			
		||||
mod view;
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
| 
						 | 
				
			
			@ -11,19 +11,22 @@ pub async fn run() {
 | 
			
		|||
    let path = args.next().expect("Cannot get binary path");
 | 
			
		||||
    let path = Path::new(&path).file_stem().unwrap().to_str().unwrap();
 | 
			
		||||
    let operation = match args.next() {
 | 
			
		||||
            Some(operation) => operation,
 | 
			
		||||
            None => {
 | 
			
		||||
                eprintln!("Missing operation, run `{} help`", path);
 | 
			
		||||
                exit(1);
 | 
			
		||||
            }
 | 
			
		||||
        Some(operation) => operation,
 | 
			
		||||
        None => {
 | 
			
		||||
            eprintln!("Missing operation, run `{} help`", path);
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    match operation.as_str() {
 | 
			
		||||
        "search" => search::run(args).await,
 | 
			
		||||
        "view" | "show" | "info" => view::run(args).await,
 | 
			
		||||
        "download" | "dl" => download::run(args).await,
 | 
			
		||||
        "help" => println!(r#"Usage: {} search QUERY
 | 
			
		||||
        "help" => println!(
 | 
			
		||||
            r#"Usage: {} search QUERY
 | 
			
		||||
  or   {} info/view/show SAUCE [SAUCE]...
 | 
			
		||||
  or   {} download/dl SAUCE [SAUCE]..."#, path, path, path),
 | 
			
		||||
  or   {} download/dl SAUCE [SAUCE]..."#,
 | 
			
		||||
            path, path, path
 | 
			
		||||
        ),
 | 
			
		||||
        _ => {
 | 
			
		||||
            eprintln!("Unknown operation, run `{} help`", path);
 | 
			
		||||
            exit(1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +1,19 @@
 | 
			
		|||
use crate::api;
 | 
			
		||||
use crate::utils;
 | 
			
		||||
use crate::structs;
 | 
			
		||||
use crate::utils;
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
use std::fs::{create_dir, rename, write};
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use std::process::exit;
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use tokio::sync::Mutex;
 | 
			
		||||
use tokio::task::JoinHandle;
 | 
			
		||||
use tokio::time::{sleep, Duration};
 | 
			
		||||
use std::fs::{rename, create_dir, write};
 | 
			
		||||
extern crate tokio;
 | 
			
		||||
extern crate reqwest;
 | 
			
		||||
extern crate tokio;
 | 
			
		||||
 | 
			
		||||
const DOWNLOAD_WORKERS: usize = 5;
 | 
			
		||||
const FAIL_DOWNLOAD_WAIT_TIME: u64 = 5000;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,14 +27,17 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
    let client = reqwest::Client::new();
 | 
			
		||||
    let mut pages_vec: Vec<(String, String)> = Vec::new();
 | 
			
		||||
    {
 | 
			
		||||
        let mut handles: Vec<JoinHandle<structs::GalleryInfoSuccess>> = Vec::with_capacity(sauces.len());
 | 
			
		||||
        let mut handles: Vec<JoinHandle<structs::GalleryInfoSuccess>> =
 | 
			
		||||
            Vec::with_capacity(sauces.len());
 | 
			
		||||
        let mut sauce_info_vec: Vec<structs::GalleryInfoSuccess> = Vec::with_capacity(sauces.len());
 | 
			
		||||
        for sauce in sauces {
 | 
			
		||||
            let cloned_client = client.clone();
 | 
			
		||||
            handles.push(tokio::spawn(async move {
 | 
			
		||||
                match api::get_sauce_info(cloned_client, sauce).await.unwrap() {
 | 
			
		||||
                    structs::GalleryInfo::Info(sauce_info) => sauce_info,
 | 
			
		||||
                    structs::GalleryInfo::Error(sauce_error) => panic!("{} returned: {}", sauce, sauce_error.error)
 | 
			
		||||
                    structs::GalleryInfo::Error(sauce_error) => {
 | 
			
		||||
                        panic!("{} returned: {}", sauce, sauce_error.error)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +51,8 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
                Ok(()) => write(base_path.join("info.txt"), format!("{}\n", &sauce_info)).unwrap(),
 | 
			
		||||
                Err(err) => match err.kind() {
 | 
			
		||||
                    std::io::ErrorKind::AlreadyExists => (),
 | 
			
		||||
                    _ => panic!("Got a weird error while creating dir: {}", err)
 | 
			
		||||
                }
 | 
			
		||||
                    _ => panic!("Got a weird error while creating dir: {}", err),
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
            let mut page_num: i32 = 1;
 | 
			
		||||
            for page in sauce_info.images.pages {
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +60,7 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
                    "j" => ".jpg",
 | 
			
		||||
                    "p" => ".png",
 | 
			
		||||
                    "g" => ".gif",
 | 
			
		||||
                    _ => panic!("Unknown extension type: {}", page.t)
 | 
			
		||||
                    _ => panic!("Unknown extension type: {}", page.t),
 | 
			
		||||
                };
 | 
			
		||||
                let mut file_name = page_num.to_string();
 | 
			
		||||
                file_name.push_str(file_ext);
 | 
			
		||||
| 
						 | 
				
			
			@ -65,9 +68,10 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
                if !file_path.exists() {
 | 
			
		||||
                    pages_vec.push((
 | 
			
		||||
                        String::from(file_path.to_str().unwrap()),
 | 
			
		||||
                        format!("https://i.nhentai.net/galleries/{}/{}",
 | 
			
		||||
                            sauce_info.media_id,
 | 
			
		||||
                            file_name)
 | 
			
		||||
                        format!(
 | 
			
		||||
                            "https://i.nhentai.net/galleries/{}/{}",
 | 
			
		||||
                            sauce_info.media_id, file_name
 | 
			
		||||
                        ),
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
                page_num += 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -101,8 +105,11 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
                            if success {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        Err(err) => eprintln!("[DW{}] Failed to download {} due to {}, sleeping for {}ms", worker_id, file_path, err, FAIL_DOWNLOAD_WAIT_TIME)
 | 
			
		||||
                        }
 | 
			
		||||
                        Err(err) => eprintln!(
 | 
			
		||||
                            "[DW{}] Failed to download {} due to {}, sleeping for {}ms",
 | 
			
		||||
                            worker_id, file_path, err, FAIL_DOWNLOAD_WAIT_TIME
 | 
			
		||||
                        ),
 | 
			
		||||
                    };
 | 
			
		||||
                    sleep(Duration::from_millis(FAIL_DOWNLOAD_WAIT_TIME)).await;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -116,18 +123,19 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn download_file(client: reqwest::Client, url: &str, file_name: &str) -> Result<bool, reqwest::Error> {
 | 
			
		||||
    let resp = client.get(url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await?;
 | 
			
		||||
async fn download_file(
 | 
			
		||||
    client: reqwest::Client,
 | 
			
		||||
    url: &str,
 | 
			
		||||
    file_name: &str,
 | 
			
		||||
) -> Result<bool, reqwest::Error> {
 | 
			
		||||
    let resp = client.get(url).send().await?;
 | 
			
		||||
    Ok(match resp.headers().get("Content-Type") {
 | 
			
		||||
        Some(header) if header.to_str().unwrap_or_default().starts_with("image/") => {
 | 
			
		||||
            let bytes = resp.bytes().await?;
 | 
			
		||||
            let mut file = File::create(&file_name).unwrap();
 | 
			
		||||
            file.write_all(&bytes).unwrap();
 | 
			
		||||
            true
 | 
			
		||||
        },
 | 
			
		||||
        _ => false
 | 
			
		||||
        }
 | 
			
		||||
        _ => false,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,9 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
        eprintln!("Missing search query");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    let search_info = api::get_search_info(reqwest::Client::new(), &query).await.unwrap();
 | 
			
		||||
    let search_info = api::get_search_info(reqwest::Client::new(), &query)
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    if search_info.num_pages < 1 {
 | 
			
		||||
        eprintln!("No results found");
 | 
			
		||||
        exit(1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
use crate::api;
 | 
			
		||||
use crate::utils;
 | 
			
		||||
use crate::structs;
 | 
			
		||||
use crate::utils;
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::process::exit;
 | 
			
		||||
use tokio::task::JoinHandle;
 | 
			
		||||
extern crate tokio;
 | 
			
		||||
extern crate reqwest;
 | 
			
		||||
extern crate tokio;
 | 
			
		||||
 | 
			
		||||
pub async fn run(args: env::Args) {
 | 
			
		||||
    let sauces = utils::get_arg_sauces(args).unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -15,11 +15,15 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    let client = reqwest::Client::new();
 | 
			
		||||
    let mut handles: Vec<JoinHandle<(structs::GalleryInfo, i32)>> = Vec::with_capacity(sauces.len());
 | 
			
		||||
    let mut handles: Vec<JoinHandle<(structs::GalleryInfo, i32)>> =
 | 
			
		||||
        Vec::with_capacity(sauces.len());
 | 
			
		||||
    for sauce in sauces {
 | 
			
		||||
        let cloned_client = client.clone();
 | 
			
		||||
        handles.push(tokio::spawn(async move {
 | 
			
		||||
            (api::get_sauce_info(cloned_client, sauce).await.unwrap(), sauce)
 | 
			
		||||
            (
 | 
			
		||||
                api::get_sauce_info(cloned_client, sauce).await.unwrap(),
 | 
			
		||||
                sauce,
 | 
			
		||||
            )
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
    let mut fail = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +36,7 @@ pub async fn run(args: env::Args) {
 | 
			
		|||
                    println!("");
 | 
			
		||||
                }
 | 
			
		||||
                println!("{}", &sauce_info);
 | 
			
		||||
            },
 | 
			
		||||
            }
 | 
			
		||||
            structs::GalleryInfo::Error(sauce_error) => {
 | 
			
		||||
                if one_done {
 | 
			
		||||
                    eprintln!("");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
mod api;
 | 
			
		||||
mod utils;
 | 
			
		||||
mod structs;
 | 
			
		||||
mod commands;
 | 
			
		||||
mod structs;
 | 
			
		||||
mod utils;
 | 
			
		||||
 | 
			
		||||
extern crate tokio;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
use std::fmt;
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
use std::collections::BTreeMap;
 | 
			
		||||
use serde::de::{self, Visitor};
 | 
			
		||||
use serde::{Deserialize, Deserializer};
 | 
			
		||||
use std::collections::BTreeMap;
 | 
			
		||||
use std::fmt;
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
pub struct GalleryTitleInfo {
 | 
			
		||||
| 
						 | 
				
			
			@ -15,14 +15,14 @@ pub struct GalleryTitleInfo {
 | 
			
		|||
pub struct GalleryImageInfo {
 | 
			
		||||
    pub t: String,
 | 
			
		||||
    pub w: i32,
 | 
			
		||||
    pub h: i32
 | 
			
		||||
    pub h: i32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
pub struct GalleryImagesInfo {
 | 
			
		||||
    pub pages: Vec<GalleryImageInfo>,
 | 
			
		||||
    pub cover: GalleryImageInfo,
 | 
			
		||||
    pub thumbnail: GalleryImageInfo
 | 
			
		||||
    pub thumbnail: GalleryImageInfo,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ pub struct GalleryTagInfo {
 | 
			
		|||
    pub r#type: String,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub url: String,
 | 
			
		||||
    pub count: i32
 | 
			
		||||
    pub count: i32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
| 
						 | 
				
			
			@ -45,26 +45,26 @@ pub struct GalleryInfoSuccess {
 | 
			
		|||
    pub upload_date: i32,
 | 
			
		||||
    pub tags: Vec<GalleryTagInfo>,
 | 
			
		||||
    pub num_pages: i32,
 | 
			
		||||
    pub num_favorites: i32
 | 
			
		||||
    pub num_favorites: i32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
pub struct GalleryInfoError {
 | 
			
		||||
    pub error: String
 | 
			
		||||
    pub error: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
#[serde(untagged)]
 | 
			
		||||
pub enum GalleryInfo {
 | 
			
		||||
    Info(GalleryInfoSuccess),
 | 
			
		||||
    Error(GalleryInfoError)
 | 
			
		||||
    Error(GalleryInfoError),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize, Debug)]
 | 
			
		||||
pub struct SearchInfo {
 | 
			
		||||
    pub result: Vec<GalleryInfoSuccess>,
 | 
			
		||||
    pub num_pages: i32,
 | 
			
		||||
    pub per_page: i32
 | 
			
		||||
    pub per_page: i32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for GalleryInfoSuccess {
 | 
			
		||||
| 
						 | 
				
			
			@ -96,23 +96,25 @@ impl fmt::Display for GalleryInfoSuccess {
 | 
			
		|||
                "group" => "Groups",
 | 
			
		||||
                "language" => "Languages",
 | 
			
		||||
                "category" => "Categories",
 | 
			
		||||
                _ => tag_key
 | 
			
		||||
                _ => tag_key,
 | 
			
		||||
            };
 | 
			
		||||
            text.push_str(&format!("\n{}: {}", tag_key, tag_value.join(", ")));
 | 
			
		||||
        }
 | 
			
		||||
        text.push_str(&format!("\nPages: {}\nFavorites: {}", self.num_pages, self.num_favorites));
 | 
			
		||||
        text.push_str(&format!(
 | 
			
		||||
            "\nPages: {}\nFavorites: {}",
 | 
			
		||||
            self.num_pages, self.num_favorites
 | 
			
		||||
        ));
 | 
			
		||||
        formatter.write_str(&text)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn convert_to_i32<'de, D>(deserializer: D) -> Result<i32, D::Error>
 | 
			
		||||
where
 | 
			
		||||
    D: Deserializer<'de>
 | 
			
		||||
    D: Deserializer<'de>,
 | 
			
		||||
{
 | 
			
		||||
    struct ConvertToI32<T>(PhantomData<fn() -> T>);
 | 
			
		||||
 | 
			
		||||
    impl<'de> Visitor<'de> for ConvertToI32<i32>
 | 
			
		||||
    {
 | 
			
		||||
    impl<'de> Visitor<'de> for ConvertToI32<i32> {
 | 
			
		||||
        type Value = i32;
 | 
			
		||||
 | 
			
		||||
        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
 | 
			
		||||
| 
						 | 
				
			
			@ -121,28 +123,28 @@ where
 | 
			
		|||
 | 
			
		||||
        fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            Ok(i32::from(value))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            Ok(i32::from(value))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            Ok(value)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            use std::i32;
 | 
			
		||||
            if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) {
 | 
			
		||||
| 
						 | 
				
			
			@ -154,21 +156,21 @@ where
 | 
			
		|||
 | 
			
		||||
        fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            Ok(i32::from(value))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            Ok(i32::from(value))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            use std::{i32, u32};
 | 
			
		||||
            if value <= i32::MAX as u32 {
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +182,7 @@ where
 | 
			
		|||
 | 
			
		||||
        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
            use std::{i32, u64};
 | 
			
		||||
            if value <= i32::MAX as u64 {
 | 
			
		||||
| 
						 | 
				
			
			@ -192,9 +194,9 @@ where
 | 
			
		|||
 | 
			
		||||
        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
 | 
			
		||||
        where
 | 
			
		||||
            E: de::Error
 | 
			
		||||
            E: de::Error,
 | 
			
		||||
        {
 | 
			
		||||
//            https://brokenco.de/2020/08/03/serde-deserialize-with-string.html
 | 
			
		||||
            // https://brokenco.de/2020/08/03/serde-deserialize-with-string.html
 | 
			
		||||
            value.parse::<i32>().map_err(serde::de::Error::custom)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,10 +4,10 @@ pub fn get_arg_sauces(args: env::Args) -> Result<Vec<i32>, String> {
 | 
			
		|||
    let mut sauces: Vec<i32> = Vec::new();
 | 
			
		||||
    for sauce in args {
 | 
			
		||||
        let sauce: i32 = match sauce.parse() {
 | 
			
		||||
                Ok(sauce) => sauce,
 | 
			
		||||
                Err(_) => {
 | 
			
		||||
                    return Err(format!("{} is not a number/sauce", sauce));
 | 
			
		||||
                }
 | 
			
		||||
            Ok(sauce) => sauce,
 | 
			
		||||
            Err(_) => {
 | 
			
		||||
                return Err(format!("{} is not a number/sauce", sauce));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if !sauces.contains(&sauce) {
 | 
			
		||||
            sauces.push(sauce);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue