1use std::io::Write;
2use std::sync::Arc;
3
4use crate::api_traits::TrendingProjectURL;
5use crate::config::ConfigProperties;
6use crate::display::{Column, DisplayBody};
7use crate::remote::{self, CacheType, GetRemoteCliArgs};
8use crate::Result;
9
10use super::common;
11
12pub struct TrendingCliArgs {
13 pub language: String,
14 pub get_args: GetRemoteCliArgs,
15 pub flush: bool,
17}
18
19#[derive(Clone)]
20pub struct TrendingProject {
21 pub url: String,
22 pub description: String,
23}
24
25impl TrendingProject {
26 pub fn new(url: String, description: String) -> Self {
27 Self { url, description }
28 }
29}
30
31impl From<TrendingProject> for DisplayBody {
32 fn from(trpr: TrendingProject) -> Self {
33 DisplayBody::new(vec![
34 Column::new("URL", trpr.url),
35 Column::builder()
36 .name("Description".to_string())
37 .value(trpr.description)
38 .optional(true)
39 .build()
40 .unwrap(),
41 ])
42 }
43}
44
45pub fn execute(
46 cli_args: TrendingCliArgs,
47 config: Arc<dyn ConfigProperties>,
48 domain: &str,
49) -> Result<()> {
50 let remote = remote::get_trending(
51 domain.to_string(),
52 "".to_string(),
55 config,
56 Some(&cli_args.get_args.cache_args),
57 CacheType::File,
58 )?;
59 get_urls(remote, cli_args, &mut std::io::stdout())
60}
61
62fn get_urls<W: Write>(
63 remote: Arc<dyn TrendingProjectURL>,
64 cli_args: TrendingCliArgs,
65 writer: &mut W,
66) -> Result<()> {
67 common::list_trending(remote, cli_args.language.to_string(), cli_args, writer)
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[derive(Default)]
75 struct MockTrendingProjectURL {
76 projects: Vec<TrendingProject>,
77 }
78
79 impl MockTrendingProjectURL {
80 fn new(projects: Vec<TrendingProject>) -> Self {
81 Self { projects }
82 }
83 }
84
85 impl TrendingProjectURL for MockTrendingProjectURL {
86 fn list(&self, _language: String) -> Result<Vec<TrendingProject>> {
87 Ok(self.projects.clone())
88 }
89 }
90
91 #[test]
92 fn test_no_urls() {
93 let remote = Arc::new(MockTrendingProjectURL::default());
94 let cli_args = TrendingCliArgs {
95 language: "rust".to_string(),
96 get_args: GetRemoteCliArgs::builder().build().unwrap(),
97 flush: false,
98 };
99 let mut buf = Vec::new();
100 get_urls(remote, cli_args, &mut buf).unwrap();
101 assert_eq!("No resources found.\n", String::from_utf8(buf).unwrap(),)
102 }
103
104 #[test]
105 fn test_trending_projects() {
106 let projects = vec![
107 TrendingProject::new(
108 "https://github.com/kubernetes/kubernetes".to_string(),
109 "".to_string(),
110 ),
111 TrendingProject::new(
112 "https://github.com/jordilin/gitar".to_string(),
113 "".to_string(),
114 ),
115 ];
116 let remote = Arc::new(MockTrendingProjectURL::new(projects));
117 let cli_args = TrendingCliArgs {
118 language: "rust".to_string(),
119 get_args: GetRemoteCliArgs::builder().build().unwrap(),
120 flush: false,
121 };
122 let mut buf = Vec::new();
123 get_urls(remote, cli_args, &mut buf).unwrap();
124 assert_eq!(
125 "URL\nhttps://github.com/kubernetes/kubernetes\nhttps://github.com/jordilin/gitar\n",
126 String::from_utf8(buf).unwrap(),
127 )
128 }
129}