use std::{error::Error, collections::HashMap};
use serde::Deserialize;
use super::{models::*, TOKEN};
#[derive(Debug, Deserialize)]
pub struct UpdateAnime {
id: u32,
params: HashMap<String, String>,
}
impl UpdateAnime {
pub fn new(id: u32) -> Self {
UpdateAnime {
id,
params: HashMap::new(),
}
}
pub fn from_malanimedata(mal_data: &MalAnimeData) -> Self {
UpdateAnime {
id: mal_data.id,
params: HashMap::new(),
}
}
pub async fn update(&mut self) -> Result<ListStatus, Box<dyn Error>> {
let url = format!("https://api.myanimelist.net/v2/anime/{}/my_list_status", self.id);
let token = TOKEN.lock()?;
if token.is_empty() { return Err("User is not logged in")? }
let client = reqwest::Client::new();
let res = client
.put(url)
.header("Authorization", format!("Bearer {}", *token))
.form(&self.params)
.send()
.await?;
if res.status().is_success() {
let data = res.text().await?;
let result: ListStatus = serde_json::from_str(&data)?;
return Ok(result);
} else {
return Err(format!("Request failed with status {:?}", res.status()))?;
}
}
pub fn update_status(&mut self, new_status: Status) -> &mut Self {
let s: &str;
match new_status {
Status::Completed => s = "completed",
Status::Dropped => s = "dropped",
Status::OnHold => s = "on_hold",
Status::PlanToWatch => s = "plan_to_watch",
Status::Watching => s = "watching",
}
self.params.insert("status".to_string(), s.to_string());
self
}
pub fn update_is_rewatching(&mut self, new_is_rewatching: bool) -> &mut Self {
self.params.insert("is_rewatching".to_string(), new_is_rewatching.to_string());
self
}
pub fn update_score(&mut self, new_score: u32) -> Result<&mut Self, Box<dyn Error>> {
if new_score > 10 { return Err("Score has to be 0-10")? }
self.params.insert("score".to_string(), new_score.to_string());
Ok(self)
}
pub fn update_num_watched_episodes(&mut self, new_num_watched_episodes: u32) -> &mut Self {
self.params.insert("num_watched_episodes".to_string(), new_num_watched_episodes.to_string());
self
}
pub fn update_priority(&mut self, new_priority: u32) -> Result<&mut Self, Box<dyn Error>> {
if new_priority > 2 { return Err("Priority has to be 0-2")? }
self.params.insert("priority".to_string(), new_priority.to_string());
Ok(self)
}
pub fn update_num_times_rewatched(&mut self, new_num_times_rewatched: u32) -> &mut Self {
self.params.insert("num_times_rewatched".to_string(), new_num_times_rewatched.to_string());
self
}
pub fn update_rewatch_value(&mut self, new_rewatch_value: u32) -> Result<&mut Self, Box<dyn Error>> {
if new_rewatch_value > 5 { return Err("rewatch_value has to be 0-5")? }
self.params.insert("rewatch_value".to_string(), new_rewatch_value.to_string());
Ok(self)
}
pub fn update_tags(&mut self, new_tags: Vec<&str>) -> &mut Self {
self.params.insert("tags".to_string(), new_tags.join(","));
self
}
pub fn update_comments(&mut self, new_comments: &str) -> &mut Self {
self.params.insert("comments".to_string(), new_comments.to_string());
self
}
pub fn update_start_date(&mut self, new_year: u32, new_month: u32, new_day: u32) -> &mut Self {
let new_start_date = format!("{:04}-{:02}-{:02}", new_year, new_month, new_day);
self.params.insert("start_date".to_string(), new_start_date.to_string());
self
}
pub fn update_finish_date(&mut self, new_year: u32, new_month: u32, new_day: u32) -> &mut Self {
let new_finish_date = format!("{:04}-{:02}-{:02}", new_year, new_month, new_day);
self.params.insert("finish_date".to_string(), new_finish_date.to_string());
self
}
}
pub async fn delete_anime(id: u32) -> Result<(), Box<dyn Error>> {
let url = format!("https://api.myanimelist.net/v2/anime/{id}/my_list_status");
let token = TOKEN.lock()?;
if token.is_empty() { return Err("User is not logged in")? }
let client = reqwest::Client::new();
let res = client
.delete(url)
.header("Authorization", format!("Bearer {}", *token))
.send()
.await?;
match res.status().is_success() {
true => Ok(()),
false => Err(format!("Request failed with status {:?}", res.status()))?,
}
}