From fddb65d9a79a9f5e56f5401320c80834e96a9422 Mon Sep 17 00:00:00 2001 From: Thaumy Date: Wed, 27 Sep 2023 11:43:12 +0800 Subject: [PATCH] refactor: lift out rev --- src/display/colorful.rs | 245 +++++++++++++++++++--------------------- src/display/json.rs | 53 ++++----- src/display/mod.rs | 54 ++++----- src/display/normal.rs | 237 ++++++++++++++++++-------------------- src/infra/iter.rs | 16 +++ src/main.rs | 52 +++++---- 6 files changed, 324 insertions(+), 333 deletions(-) diff --git a/src/display/colorful.rs b/src/display/colorful.rs index bfae13c..4d9c62e 100644 --- a/src/display/colorful.rs +++ b/src/display/colorful.rs @@ -9,7 +9,6 @@ use crate::api::post::get_comment_list::PostCommentEntry; use crate::api::post::get_one::PostEntry; use crate::api::user::info::UserInfo; use crate::args::TimeStyle; -use crate::infra::iter::IteratorExt; use crate::infra::result::IntoResult; use crate::infra::str::StrExt; use crate::infra::terminal::get_term_width; @@ -78,103 +77,94 @@ pub fn user_info(info: &Result) -> Result { // TODO: rm unnecessary line divider pub fn list_ing( time_style: &TimeStyle, - ing_with_comment_list: &Result)>>, - rev: bool, + ing_with_comment_iter: Result)>>, align: bool, ) -> Result { - let ing_with_comment_list = match ing_with_comment_list { + let mut ing_with_comment_iter = match ing_with_comment_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - ing_with_comment_list.iter().dyn_rev(rev).try_fold( - String::new(), - |mut buf, (ing, comment_list)| try { - { - let buf = &mut buf; - let create_time = display_cnb_time(&ing.create_time, time_style); - write!(buf, "{}", create_time.dimmed())?; + ing_with_comment_iter.try_fold(String::new(), |mut buf, (ing, comment_list)| try { + { + let buf = &mut buf; + let create_time = display_cnb_time(&ing.create_time, time_style); + write!(buf, "{}", create_time.dimmed())?; - let send_from_mark = match ing.send_from { - IngSendFrom::Cli => Some("CLI"), - IngSendFrom::CellPhone => Some("Mobile"), - IngSendFrom::VsCode => Some("VSCode"), - IngSendFrom::Web => Some("Web"), - _ => None, - }; - if let Some(mark) = send_from_mark { - write!(buf, " {}", mark.dimmed())?; - } - if ing.is_lucky { - let star_text = ing_star_tag_to_text(&ing.icons); - write!(buf, " {}⭐", star_text.yellow())?; - } - writeln!(buf, " {} {}", "#".dimmed(), ing.id.to_string().dimmed())?; - let content = if align { - let user_name_width = ing.user_name.width_cjk(); - let left_width = get_term_width().saturating_sub(user_name_width + 3); - fmt_content(&ing.content) - .width_split(left_width) - .map_or_else( - || ing.content.clone(), - |lines| { - if comment_list.is_empty().not() { - lines.join("\n").replace( - '\n', - &format!("\n │{}", " ".repeat(user_name_width - 2)), - ) - } else { - lines.join("\n").replace( - '\n', - &format!("\n{}", " ".repeat(user_name_width + 3)), - ) - } - }, - ) - } else { - fmt_content(&ing.content) - }; - writeln!(buf, " {} {}", ing.user_name.cyan(), content)?; + let send_from_mark = match ing.send_from { + IngSendFrom::Cli => Some("CLI"), + IngSendFrom::CellPhone => Some("Mobile"), + IngSendFrom::VsCode => Some("VSCode"), + IngSendFrom::Web => Some("Web"), + _ => None, + }; + if let Some(mark) = send_from_mark { + write!(buf, " {}", mark.dimmed())?; + } + if ing.is_lucky { + let star_text = ing_star_tag_to_text(&ing.icons); + write!(buf, " {}⭐", star_text.yellow())?; + } + writeln!(buf, " {} {}", "#".dimmed(), ing.id.to_string().dimmed())?; + let content = if align { + let user_name_width = ing.user_name.width_cjk(); + let left_width = get_term_width().saturating_sub(user_name_width + 3); + fmt_content(&ing.content) + .width_split(left_width) + .map_or_else( + || ing.content.clone(), + |lines| { + if comment_list.is_empty().not() { + lines.join("\n").replace( + '\n', + &format!("\n │{}", " ".repeat(user_name_width - 2)), + ) + } else { + lines.join("\n").replace( + '\n', + &format!("\n{}", " ".repeat(user_name_width + 3)), + ) + } + }, + ) + } else { + fmt_content(&ing.content) + }; + writeln!(buf, " {} {}", ing.user_name.cyan(), content)?; - let len = comment_list.len(); - if len != 0 { - let max_i = len - 1; - let comment_list_buf: Result = comment_list - .iter() - .enumerate() - .try_fold(String::new(), |mut buf, (i, entry)| try { - { - let buf = &mut buf; - if i != max_i { - write!(buf, " │ {}", entry.user_name.blue())?; - } else { - write!(buf, " └ {}", entry.user_name.blue())?; - } - let at_user = get_ing_at_user_tag_text(&entry.content); - if at_user.is_empty().not() { - write!( - buf, - " {}{}", - "@".bright_black(), - at_user.bright_black() - )?; - } - let content = { - let content = rm_ing_at_user_tag(&entry.content); - fmt_content(&content) - }; - writeln!(buf, " {}", content.dimmed())?; + let len = comment_list.len(); + if len != 0 { + let max_i = len - 1; + let comment_list_buf: Result = comment_list.iter().enumerate().try_fold( + String::new(), + |mut buf, (i, entry)| try { + { + let buf = &mut buf; + if i != max_i { + write!(buf, " │ {}", entry.user_name.blue())?; + } else { + write!(buf, " └ {}", entry.user_name.blue())?; } - buf - }); - write!(buf, "{}", comment_list_buf?)?; - } + let at_user = get_ing_at_user_tag_text(&entry.content); + if at_user.is_empty().not() { + write!(buf, " {}{}", "@".bright_black(), at_user.bright_black())?; + } + let content = { + let content = rm_ing_at_user_tag(&entry.content); + fmt_content(&content) + }; + writeln!(buf, " {}", content.dimmed())?; + } + buf + }, + ); + write!(buf, "{}", comment_list_buf?)?; + } - writeln!(buf)?; - }; - buf - }, - ) + writeln!(buf)?; + }; + buf + }) } pub fn show_post(entry: &Result) -> Result { @@ -240,37 +230,35 @@ pub fn show_post_meta(time_style: &TimeStyle, entry: &Result) -> Resu pub fn show_post_comment( time_style: &TimeStyle, - comment_list: &Result>, - rev: bool, + comment_iter: Result>, ) -> Result { - let comment_list = match comment_list { + let mut comment_iter = match comment_iter { Ok(entry) => entry, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - comment_list - .iter() - .dyn_rev(rev) - .try_fold(String::new(), |mut buf, comment| try { - { - let buf = &mut buf; - let create_time = display_cnb_time(&comment.create_time, time_style); - let floor_text = format!("{}F", comment.floor); - writeln!(buf, "{} {}", create_time.dimmed(), floor_text.dimmed())?; - writeln!(buf, " {} {}", comment.user_name.cyan(), comment.content)?; - } - buf - }) + comment_iter.try_fold(String::new(), |mut buf, comment| try { + { + let buf = &mut buf; + let create_time = display_cnb_time(&comment.create_time, time_style); + let floor_text = format!("{}F", comment.floor); + writeln!(buf, "{} {}", create_time.dimmed(), floor_text.dimmed())?; + writeln!(buf, " {} {}", comment.user_name.cyan(), comment.content)?; + } + buf + }) } -pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> Result { - let (entry_list, total_count) = match result { +pub fn list_post( + result: Result<(impl ExactSizeIterator, usize)>, +) -> Result { + let (mut entry_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - entry_list.iter().dyn_rev(rev).try_fold( - format!("{}/{}\n", entry_list.len(), total_count), + entry_iter.try_fold( + format!("{}/{}\n", entry_iter.len(), total_count), |mut buf, entry| try { { let buf = &mut buf; @@ -291,14 +279,16 @@ pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> Result< ) } -pub fn search_post(result: &Result<(Vec, usize)>, rev: bool) -> Result { - let (id_list, total_count) = match result { +pub fn search_post( + result: Result<(impl ExactSizeIterator, usize)>, +) -> Result { + let (mut id_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - id_list.iter().dyn_rev(rev).try_fold( - format!("{}/{}\n", id_list.len(), total_count), + id_iter.try_fold( + format!("{}/{}\n", id_iter.len(), total_count), |mut buf, id| try { writeln!(&mut buf, "# {}", id)?; buf @@ -308,17 +298,14 @@ pub fn search_post(result: &Result<(Vec, usize)>, rev: bool) -> Result>, - rev: bool, + news_iter: Result>, ) -> Result { - let news_list = match news_list { + let news_iter = match news_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - news_list - .iter() - .dyn_rev(rev) + news_iter .map(|news| try { let mut buf = String::new(); { @@ -350,20 +337,16 @@ pub fn list_news( }) } -// TODO: lift out rev option pub fn list_fav( time_style: &TimeStyle, - fav_list: &Result>, - rev: bool, + fav_iter: Result>, ) -> Result { - let fav_list = match fav_list { + let fav_iter = match fav_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - fav_list - .iter() - .dyn_rev(rev) + fav_iter .map(|fav| try { let mut buf = String::new(); { diff --git a/src/display/json.rs b/src/display/json.rs index 5f3a1b1..e7630a2 100644 --- a/src/display/json.rs +++ b/src/display/json.rs @@ -5,7 +5,6 @@ use crate::api::news::get_list::NewsEntry; use crate::api::post::get_comment_list::PostCommentEntry; use crate::api::post::get_one::PostEntry; use crate::api::user::info::UserInfo; -use crate::infra::iter::IteratorExt; use crate::infra::json; use crate::infra::result::IntoResult; use anyhow::Result; @@ -37,17 +36,14 @@ pub fn user_info(info: &Result) -> String { } pub fn list_ing( - ing_with_comment_list: &Result)>>, - rev: bool, + ing_with_comment_list: Result)>>, ) -> Result { let ing_with_comment_list = match ing_with_comment_list { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; let json_vec = ing_with_comment_list - .iter() - .dyn_rev(rev) .map(|(entry, comment_list)| { json!({ "entry": entry, @@ -74,25 +70,24 @@ pub fn show_post_meta(entry: &Result) -> String { } pub fn show_post_comment( - comment_list: &Result>, - rev: bool, + comment_iter: Result>, ) -> Result { - let comment_list = match comment_list { + let comment_iter = match comment_iter { Ok(entry) => entry, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - let comment_vec = comment_list.iter().dyn_rev(rev).collect::>(); + let comment_vec = comment_iter.collect::>(); json::serialize(comment_vec) } -pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> String { - let (entry_list, total_count) = match result { +pub fn list_post(result: Result<(impl ExactSizeIterator, usize)>) -> String { + let (entry_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e), + Err(e) => return fmt_err(&e), }; - let vec = entry_list.iter().dyn_rev(rev).collect::>(); + let vec = entry_iter.collect::>(); let json = json!({ "listed_count": vec.len(), "total_count": total_count, @@ -101,13 +96,13 @@ pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> String json.to_string() } -pub fn search_post(result: &Result<(Vec, usize)>, rev: bool) -> String { - let (id_list, total_count) = match result { +pub fn search_post(result: Result<(impl ExactSizeIterator, usize)>) -> String { + let (id_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e), + Err(e) => return fmt_err(&e), }; - let id_list = id_list.iter().dyn_rev(rev).collect::>(); + let id_list = id_iter.collect::>(); let json = json!({ "listed_count": id_list.len(), "total_count": total_count, @@ -130,24 +125,24 @@ pub fn fmt_result(result: &Result) -> String { json.to_string() } -pub fn list_news(news_list: &Result>, rev: bool) -> Result { - let news_list = match news_list { +pub fn list_news(news_iter: Result>) -> Result { + let news_iter = match news_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - let vec = news_list.iter().dyn_rev(rev).collect::>(); + let vec = news_iter.collect::>(); - json::serialize(vec.clone()) + json::serialize(vec) } -pub fn list_fav(news_list: &Result>, rev: bool) -> Result { - let news_list = match news_list { +pub fn list_fav(fav_iter: Result>) -> Result { + let fav_iter = match fav_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - let vec = news_list.iter().dyn_rev(rev).collect::>(); + let vec = fav_iter.collect::>(); - json::serialize(vec.clone()) + json::serialize(vec) } diff --git a/src/display/mod.rs b/src/display/mod.rs index 16ed815..7cfd0c6 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -41,14 +41,13 @@ pub fn user_info(style: &Style, user_info: &Result) -> Result pub fn list_ing( style: &Style, time_style: &TimeStyle, - ing_with_comment_list: &Result)>>, - rev: bool, + ing_with_comment_iter: Result)>>, align: bool, ) -> Result { match style { - Style::Colorful => colorful::list_ing(time_style, ing_with_comment_list, rev, align), - Style::Normal => normal::list_ing(time_style, ing_with_comment_list, rev, align), - Style::Json => json::list_ing(ing_with_comment_list, rev), + Style::Colorful => colorful::list_ing(time_style, ing_with_comment_iter, align), + Style::Normal => normal::list_ing(time_style, ing_with_comment_iter, align), + Style::Json => json::list_ing(ing_with_comment_iter), } } @@ -91,25 +90,23 @@ pub fn show_post_meta( pub fn show_post_comment( style: &Style, time_style: &TimeStyle, - comment_list: &Result>, - rev: bool, + comment_iter: Result>, ) -> Result { match style { - Style::Colorful => colorful::show_post_comment(time_style, comment_list, rev), - Style::Normal => normal::show_post_comment(time_style, comment_list, rev), - Style::Json => json::show_post_comment(comment_list, rev), + Style::Colorful => colorful::show_post_comment(time_style, comment_iter), + Style::Normal => normal::show_post_comment(time_style, comment_iter), + Style::Json => json::show_post_comment(comment_iter), } } pub fn list_post( style: &Style, - result: &Result<(Vec, usize)>, - rev: bool, + result: Result<(impl ExactSizeIterator, usize)>, ) -> Result { match style { - Style::Colorful => colorful::list_post(result, rev), - Style::Normal => normal::list_post(result, rev), - Style::Json => json::list_post(result, rev).into_ok(), + Style::Colorful => colorful::list_post(result), + Style::Normal => normal::list_post(result), + Style::Json => json::list_post(result).into_ok(), } } @@ -123,13 +120,12 @@ pub fn delete_post(style: &Style, result: &Result) -> String { pub fn search_post( style: &Style, - result: &Result<(Vec, usize)>, - rev: bool, + result: Result<(impl ExactSizeIterator, usize)>, ) -> Result { match style { - Style::Colorful => colorful::search_post(result, rev), - Style::Normal => normal::search_post(result, rev), - Style::Json => json::search_post(result, rev).into_ok(), + Style::Colorful => colorful::search_post(result), + Style::Normal => normal::search_post(result), + Style::Json => json::search_post(result).into_ok(), } } @@ -152,25 +148,23 @@ pub fn update_post(style: &Style, result: &Result) -> String { pub fn list_news( style: &Style, time_style: &TimeStyle, - news_list: &Result>, - rev: bool, + news_iter: Result>, ) -> Result { match style { - Style::Colorful => colorful::list_news(time_style, news_list, rev), - Style::Normal => normal::list_news(time_style, news_list, rev), - Style::Json => json::list_news(news_list, rev), + Style::Colorful => colorful::list_news(time_style, news_iter), + Style::Normal => normal::list_news(time_style, news_iter), + Style::Json => json::list_news(news_iter), } } pub fn list_fav( style: &Style, time_style: &TimeStyle, - fav_list: &Result>, - rev: bool, + fav_iter: Result>, ) -> Result { match style { - Style::Colorful => colorful::list_fav(time_style, fav_list, rev), - Style::Normal => normal::list_fav(time_style, fav_list, rev), - Style::Json => json::list_fav(fav_list, rev), + Style::Colorful => colorful::list_fav(time_style, fav_iter), + Style::Normal => normal::list_fav(time_style, fav_iter), + Style::Json => json::list_fav(fav_iter), } } diff --git a/src/display/normal.rs b/src/display/normal.rs index 8d8e03c..f9dbfb8 100644 --- a/src/display/normal.rs +++ b/src/display/normal.rs @@ -9,7 +9,6 @@ use crate::api::post::get_comment_list::PostCommentEntry; use crate::api::post::get_one::PostEntry; use crate::api::user::info::UserInfo; use crate::args::TimeStyle; -use crate::infra::iter::IteratorExt; use crate::infra::result::IntoResult; use crate::infra::str::StrExt; use crate::infra::terminal::get_term_width; @@ -76,98 +75,94 @@ pub fn user_info(info: &Result) -> Result { // TODO: rm unnecessary line divider pub fn list_ing( time_style: &TimeStyle, - ing_with_comment_list: &Result)>>, - rev: bool, + ing_with_comment_list: Result)>>, align: bool, ) -> Result { - let ing_with_comment_list = match ing_with_comment_list { + let mut ing_with_comment_list = match ing_with_comment_list { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - ing_with_comment_list.iter().dyn_rev(rev).try_fold( - String::new(), - |mut buf, (ing, comment_list)| try { - { - let buf = &mut buf; - let create_time = display_cnb_time(&ing.create_time, time_style); - write!(buf, "{}", create_time)?; + ing_with_comment_list.try_fold(String::new(), |mut buf, (ing, comment_list)| try { + { + let buf = &mut buf; + let create_time = display_cnb_time(&ing.create_time, time_style); + write!(buf, "{}", create_time)?; - let send_from_mark = match ing.send_from { - IngSendFrom::Cli => Some("CLI"), - IngSendFrom::CellPhone => Some("Mobile"), - IngSendFrom::VsCode => Some("VSCode"), - IngSendFrom::Web => Some("Web"), - _ => None, - }; - if let Some(mark) = send_from_mark { - write!(buf, " {}", mark)?; - } - if ing.is_lucky { - let star_text = ing_star_tag_to_text(&ing.icons); - write!(buf, " {}★", star_text)?; - } - writeln!(buf, " # {}", ing.id)?; - let content = if align { - let user_name_width = ing.user_name.width_cjk(); - let left_width = get_term_width().saturating_sub(user_name_width + 3); - fmt_content(&ing.content) - .width_split(left_width) - .map_or_else( - || ing.content.clone(), - |lines| { - if comment_list.is_empty().not() { - lines.join("\n").replace( - '\n', - &format!("\n │{}", " ".repeat(user_name_width - 2)), - ) - } else { - lines.join("\n").replace( - '\n', - &format!("\n{}", " ".repeat(user_name_width + 3)), - ) - } - }, - ) - } else { - fmt_content(&ing.content) - }; - writeln!(buf, " {}: {}", ing.user_name, content)?; + let send_from_mark = match ing.send_from { + IngSendFrom::Cli => Some("CLI"), + IngSendFrom::CellPhone => Some("Mobile"), + IngSendFrom::VsCode => Some("VSCode"), + IngSendFrom::Web => Some("Web"), + _ => None, + }; + if let Some(mark) = send_from_mark { + write!(buf, " {}", mark)?; + } + if ing.is_lucky { + let star_text = ing_star_tag_to_text(&ing.icons); + write!(buf, " {}★", star_text)?; + } + writeln!(buf, " # {}", ing.id)?; + let content = if align { + let user_name_width = ing.user_name.width_cjk(); + let left_width = get_term_width().saturating_sub(user_name_width + 3); + fmt_content(&ing.content) + .width_split(left_width) + .map_or_else( + || ing.content.clone(), + |lines| { + if comment_list.is_empty().not() { + lines.join("\n").replace( + '\n', + &format!("\n │{}", " ".repeat(user_name_width - 2)), + ) + } else { + lines.join("\n").replace( + '\n', + &format!("\n{}", " ".repeat(user_name_width + 3)), + ) + } + }, + ) + } else { + fmt_content(&ing.content) + }; + writeln!(buf, " {}: {}", ing.user_name, content)?; - let len = comment_list.len(); - if len != 0 { - let max_i = len - 1; - let comment_list_buf: Result = comment_list - .iter() - .enumerate() - .try_fold(String::new(), |mut buf, (i, entry)| try { - { - let buf = &mut buf; - if i != max_i { - write!(buf, " │ {}", entry.user_name)?; - } else { - write!(buf, " └ {}", entry.user_name)?; - } - let at_user = get_ing_at_user_tag_text(&entry.content); - if at_user.is_empty().not() { - write!(buf, " @{}", at_user)?; - } - let content = { - let content = rm_ing_at_user_tag(&entry.content); - fmt_content(&content) - }; - writeln!(buf, ": {}", content)?; + let len = comment_list.len(); + if len != 0 { + let max_i = len - 1; + let comment_list_buf: Result = comment_list.iter().enumerate().try_fold( + String::new(), + |mut buf, (i, entry)| try { + { + let buf = &mut buf; + if i != max_i { + write!(buf, " │ {}", entry.user_name)?; + } else { + write!(buf, " └ {}", entry.user_name)?; } - buf - }); - write!(buf, "{}", comment_list_buf?)?; - } + let at_user = get_ing_at_user_tag_text(&entry.content); + if at_user.is_empty().not() { + write!(buf, " @{}", at_user)?; + } + let content = { + let content = rm_ing_at_user_tag(&entry.content); + fmt_content(&content) + }; + writeln!(buf, ": {}", content)?; + } + buf + }, + ); + write!(buf, "{}", comment_list_buf?)?; + } - writeln!(buf)?; - }; - buf - }, - ) + writeln!(buf)?; + }; + buf + }) } pub fn show_post(entry: &Result) -> Result { @@ -233,36 +228,34 @@ pub fn show_post_meta(time_style: &TimeStyle, entry: &Result) -> Resu pub fn show_post_comment( time_style: &TimeStyle, - comment_list: &Result>, - rev: bool, + comment_iter: Result>, ) -> Result { - let comment_list = match comment_list { + let mut comment_iter = match comment_iter { Ok(entry) => entry, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - comment_list - .iter() - .dyn_rev(rev) - .try_fold(String::new(), |mut buf, comment| try { - { - let buf = &mut buf; - let create_time = display_cnb_time(&comment.create_time, time_style); - writeln!(buf, "{} {}F", create_time, comment.floor)?; - writeln!(buf, " {} {}", comment.user_name, comment.content)?; - } - buf - }) + comment_iter.try_fold(String::new(), |mut buf, comment| try { + { + let buf = &mut buf; + let create_time = display_cnb_time(&comment.create_time, time_style); + writeln!(buf, "{} {}F", create_time, comment.floor)?; + writeln!(buf, " {} {}", comment.user_name, comment.content)?; + } + buf + }) } -pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> Result { - let (entry_list, total_count) = match result { +pub fn list_post( + result: Result<(impl ExactSizeIterator, usize)>, +) -> Result { + let (mut entry_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - entry_list.iter().dyn_rev(rev).try_fold( - format!("{}/{}\n", entry_list.len(), total_count), + entry_iter.try_fold( + format!("{}/{}\n", entry_iter.len(), total_count), |mut buf, entry| try { { let buf = &mut buf; @@ -283,14 +276,16 @@ pub fn list_post(result: &Result<(Vec, usize)>, rev: bool) -> Result< ) } -pub fn search_post(result: &Result<(Vec, usize)>, rev: bool) -> Result { - let (id_list, total_count) = match result { +pub fn search_post( + result: Result<(impl ExactSizeIterator, usize)>, +) -> Result { + let (mut id_iter, total_count) = match result { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - id_list.iter().dyn_rev(rev).try_fold( - format!("{}/{}\n", id_list.len(), total_count), + id_iter.try_fold( + format!("{}/{}\n", id_iter.len(), total_count), |mut buf, id| try { writeln!(&mut buf, "# {}", id)?; buf @@ -300,17 +295,14 @@ pub fn search_post(result: &Result<(Vec, usize)>, rev: bool) -> Result>, - rev: bool, + news_iter: Result>, ) -> Result { - let news_list = match news_list { + let news_iter = match news_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - news_list - .iter() - .dyn_rev(rev) + news_iter .map(|news| try { let mut buf = String::new(); { @@ -344,17 +336,14 @@ pub fn list_news( pub fn list_fav( time_style: &TimeStyle, - fav_list: &Result>, - rev: bool, + fav_iter: Result>, ) -> Result { - let fav_list = match fav_list { + let fav_iter = match fav_iter { Ok(o) => o, - Err(e) => return fmt_err(e).into_ok(), + Err(e) => return fmt_err(&e).into_ok(), }; - fav_list - .iter() - .dyn_rev(rev) + fav_iter .map(|fav| try { let mut buf = String::new(); { diff --git a/src/infra/iter.rs b/src/infra/iter.rs index 9560823..1a7aafa 100644 --- a/src/infra/iter.rs +++ b/src/infra/iter.rs @@ -17,6 +17,22 @@ pub trait IteratorExt: Iterator { impl IteratorExt for I where I: Iterator {} +pub trait ExactSizeIteratorExt: ExactSizeIterator { + #[inline] + fn dyn_rev<'t>(self, rev: bool) -> Box + 't> + where + Self: DoubleEndedIterator + Sized + 't, + { + if rev { + Box::new(self.rev()) + } else { + Box::new(self) + } + } +} + +impl ExactSizeIteratorExt for I where I: ExactSizeIterator {} + pub trait IntoIteratorExt: IntoIterator { #[inline] fn join_all(self) -> JoinAll diff --git a/src/main.rs b/src/main.rs index d992371..e55ae0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use crate::args::parser::no_operation; use crate::args::{parser, Args}; use crate::infra::fp::currying::eq; use crate::infra::infer::infer; -use crate::infra::iter::IntoIteratorExt; +use crate::infra::iter::{ExactSizeIteratorExt, IntoIteratorExt}; use crate::infra::option::OptionExt; use crate::infra::result::IntoResult; use anyhow::Result; @@ -85,7 +85,7 @@ async fn main() -> Result<()> { display::user_info(style, &user_info)? } _ if let Some((skip, take, r#type, align)) = parser::list_ing(&args) => { - let ing_with_comment_list = try { + let ing_with_comment_iter = infer::>(try { let ing_api = Ing::new(pat?); let ing_vec = ing_api.get_list(skip, take, &r#type).await?; ing_vec.into_iter() @@ -97,9 +97,9 @@ async fn main() -> Result<()> { .await .into_iter() .collect::>>()? - }; - foe.then(|| panic_if_err(&ing_with_comment_list)); - display::list_ing(style, time_style, &ing_with_comment_list, rev, align)? + }).map(|vec| vec.into_iter().dyn_rev(rev)); + foe.then(|| panic_if_err(&ing_with_comment_iter)); + display::list_ing(style, time_style, ing_with_comment_iter, align)? } _ if let Some(content) = parser::publish_ing(&args) => { let content = try { @@ -128,14 +128,19 @@ async fn main() -> Result<()> { display::show_post_meta(style, time_style, &entry)? } _ if let Some(id) = parser::show_post_comment(&args) => { - let comment_vec = Post::new(pat?).get_comment_list(id).await; - foe.then(|| panic_if_err(&comment_vec)); - display::show_post_comment(style, time_style, &comment_vec, rev)? + let comment_iter = Post::new(pat?) + .get_comment_list(id).await + .map(|vec| vec.into_iter().dyn_rev(rev)); + foe.then(|| panic_if_err(&comment_iter)); + display::show_post_comment(style, time_style, comment_iter)? } _ if let Some((skip, take)) = parser::list_post(&args) => { - let meta_vec = Post::new(pat?).get_meta_list(skip, take).await; - foe.then(|| panic_if_err(&meta_vec)); - display::list_post(style, &meta_vec, rev)? + let meta_iter = Post::new(pat?) + .get_meta_list(skip, take) + .await + .map(|(vec, count)| (vec.into_iter().dyn_rev(rev), count)); + foe.then(|| panic_if_err(&meta_iter)); + display::list_post(style, meta_iter)? } _ if let Some(id) = parser::delete_post(&args) => { let id = try { @@ -146,9 +151,12 @@ async fn main() -> Result<()> { display::delete_post(style, &id) } _ if let Some((kw, skip, take)) = parser::search_post(&args) => { - let result = Post::new(pat?).search(skip, take, kw).await; + let result = Post::new(pat?) + .search(skip, take, kw) + .await + .map(|(vec, count)| (vec.into_iter().dyn_rev(rev), count)); foe.then(|| panic_if_err(&result)); - display::search_post(style, &result, rev)? + display::search_post(style, result)? } _ if let Some((title, body, publish)) = parser::create_post(&args) => { let id = Post::new(pat?).create(title, body, publish).await; @@ -161,14 +169,20 @@ async fn main() -> Result<()> { display::update_post(style, &id) } _ if let Some((skip, take)) = parser::list_news(&args) => { - let news_vec = News::new(pat?).get_list(skip, take).await; - foe.then(|| panic_if_err(&news_vec)); - display::list_news(style, time_style, &news_vec, rev)? + let news_iter = News::new(pat?) + .get_list(skip, take) + .await + .map(|vec| vec.into_iter().dyn_rev(rev)); + foe.then(|| panic_if_err(&news_iter)); + display::list_news(style, time_style, news_iter)? } _ if let Some((skip, take)) = parser::list_fav(&args) => { - let fav_vec = Fav::new(pat?).get_list(skip, take).await; - foe.then(|| panic_if_err(&fav_vec)); - display::list_fav(style, time_style, &fav_vec, rev)? + let fav_iter = Fav::new(pat?) + .get_list(skip, take) + .await + .map(|vec| vec.into_iter().dyn_rev(rev)); + foe.then(|| panic_if_err(&fav_iter)); + display::list_fav(style, time_style, fav_iter)? } _ if no_operation(&args) =>