gr/cmds/
gist.rs

1use std::{io::Write, sync::Arc};
2
3use crate::{
4    api_traits::{CodeGist, Timestamp},
5    display::{Column, DisplayBody},
6    remote::{ListBodyArgs, ListRemoteCliArgs},
7    Result,
8};
9
10use super::common;
11
12#[derive(Builder)]
13pub struct GistListCliArgs {
14    pub list_args: ListRemoteCliArgs,
15}
16
17impl GistListCliArgs {
18    pub fn builder() -> GistListCliArgsBuilder {
19        GistListCliArgsBuilder::default()
20    }
21}
22
23#[derive(Builder)]
24pub struct GistListBodyArgs {
25    pub body_args: Option<ListBodyArgs>,
26}
27
28impl GistListBodyArgs {
29    pub fn builder() -> GistListBodyArgsBuilder {
30        GistListBodyArgsBuilder::default()
31    }
32}
33
34#[derive(Builder, Clone)]
35pub struct Gist {
36    pub url: String,
37    pub description: String,
38    pub files: String,
39    pub created_at: String,
40}
41
42impl Gist {
43    pub fn builder() -> GistBuilder {
44        GistBuilder::default()
45    }
46}
47
48impl From<Gist> for DisplayBody {
49    fn from(gist: Gist) -> Self {
50        DisplayBody {
51            columns: vec![
52                Column::new("Files", gist.files),
53                Column::new("URL", gist.url),
54                Column::builder()
55                    .name("Description".to_string())
56                    .value(gist.description)
57                    .optional(true)
58                    .build()
59                    .unwrap(),
60                Column::new("Created at", gist.created_at),
61            ],
62        }
63    }
64}
65
66impl Timestamp for Gist {
67    fn created_at(&self) -> String {
68        self.created_at.clone()
69    }
70}
71
72pub fn list_user_gists<W: Write>(
73    remote: Arc<dyn CodeGist>,
74    body_args: GistListBodyArgs,
75    cli_args: GistListCliArgs,
76    writer: W,
77) -> Result<()> {
78    common::list_user_gists(remote, body_args, cli_args, writer)
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    struct GistMock;
86
87    impl CodeGist for GistMock {
88        fn list(&self, _args: GistListBodyArgs) -> Result<Vec<Gist>> {
89            let gist = Gist::builder()
90                .url("https://gist.github.com/aa5a315d61ae9438b18d".to_string())
91                .description("A gist".to_string())
92                .files("main.rs,hello_rust.rs".to_string())
93                .created_at("2021-08-01T00:00:00Z".to_string())
94                .build()
95                .unwrap();
96            Ok(vec![gist])
97        }
98
99        fn num_pages(&self) -> Result<Option<u32>> {
100            todo!()
101        }
102
103        fn num_resources(&self) -> Result<Option<crate::api_traits::NumberDeltaErr>> {
104            todo!()
105        }
106    }
107
108    #[test]
109    fn test_list_user_gists() {
110        let body_args = GistListBodyArgs::builder().body_args(None).build().unwrap();
111        let cli_args = GistListCliArgs::builder()
112            .list_args(ListRemoteCliArgs::builder().build().unwrap())
113            .build()
114            .unwrap();
115        let mut buff = Vec::new();
116        let remote = Arc::new(GistMock);
117        assert!(list_user_gists(remote, body_args, cli_args, &mut buff).is_ok());
118        assert_eq!(
119            "Files|URL|Created at\nmain.rs,hello_rust.rs|https://gist.github.com/aa5a315d61ae9438b18d|2021-08-01T00:00:00Z\n",
120            String::from_utf8(buff).unwrap()
121        );
122    }
123}