gr/cmds/
gist.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::{io::Write, sync::Arc};

use crate::{
    api_traits::{CodeGist, Timestamp},
    display::{Column, DisplayBody},
    remote::{ListBodyArgs, ListRemoteCliArgs},
    Result,
};

use super::common;

#[derive(Builder)]
pub struct GistListCliArgs {
    pub list_args: ListRemoteCliArgs,
}

impl GistListCliArgs {
    pub fn builder() -> GistListCliArgsBuilder {
        GistListCliArgsBuilder::default()
    }
}

#[derive(Builder)]
pub struct GistListBodyArgs {
    pub body_args: Option<ListBodyArgs>,
}

impl GistListBodyArgs {
    pub fn builder() -> GistListBodyArgsBuilder {
        GistListBodyArgsBuilder::default()
    }
}

#[derive(Builder, Clone)]
pub struct Gist {
    pub url: String,
    pub description: String,
    pub files: String,
    pub created_at: String,
}

impl Gist {
    pub fn builder() -> GistBuilder {
        GistBuilder::default()
    }
}

impl From<Gist> for DisplayBody {
    fn from(gist: Gist) -> Self {
        DisplayBody {
            columns: vec![
                Column::new("Files", gist.files),
                Column::new("URL", gist.url),
                Column::builder()
                    .name("Description".to_string())
                    .value(gist.description)
                    .optional(true)
                    .build()
                    .unwrap(),
                Column::new("Created at", gist.created_at),
            ],
        }
    }
}

impl Timestamp for Gist {
    fn created_at(&self) -> String {
        self.created_at.clone()
    }
}

pub fn list_user_gists<W: Write>(
    remote: Arc<dyn CodeGist>,
    body_args: GistListBodyArgs,
    cli_args: GistListCliArgs,
    writer: W,
) -> Result<()> {
    common::list_user_gists(remote, body_args, cli_args, writer)
}

#[cfg(test)]
mod tests {
    use super::*;

    struct GistMock;

    impl CodeGist for GistMock {
        fn list(&self, _args: GistListBodyArgs) -> Result<Vec<Gist>> {
            let gist = Gist::builder()
                .url("https://gist.github.com/aa5a315d61ae9438b18d".to_string())
                .description("A gist".to_string())
                .files("main.rs,hello_rust.rs".to_string())
                .created_at("2021-08-01T00:00:00Z".to_string())
                .build()
                .unwrap();
            Ok(vec![gist])
        }

        fn num_pages(&self) -> Result<Option<u32>> {
            todo!()
        }

        fn num_resources(&self) -> Result<Option<crate::api_traits::NumberDeltaErr>> {
            todo!()
        }
    }

    #[test]
    fn test_list_user_gists() {
        let body_args = GistListBodyArgs::builder().body_args(None).build().unwrap();
        let cli_args = GistListCliArgs::builder()
            .list_args(ListRemoteCliArgs::builder().build().unwrap())
            .build()
            .unwrap();
        let mut buff = Vec::new();
        let remote = Arc::new(GistMock);
        assert!(list_user_gists(remote, body_args, cli_args, &mut buff).is_ok());
        assert_eq!(
            "Files|URL|Created at\nmain.rs,hello_rust.rs|https://gist.github.com/aa5a315d61ae9438b18d|2021-08-01T00:00:00Z\n",
            String::from_utf8(buff).unwrap()
        );
    }
}