Created
January 21, 2018 04:41
-
-
Save sourcepirate/b991bf3ed0f8682cccd19311be5834cf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::default::Default; | |
use std::collections::HashMap; | |
use github_rs::StatusCode; | |
use github_rs::client::{Executor, Github}; | |
use github_rs::gists; | |
use serde_json::Value; | |
use chrono::prelude::*; | |
use reqwest; | |
use macros; | |
#[derive(Debug, Deserialize, Serialize)] | |
pub struct GistFile { | |
size: u64, | |
raw_url: Option<String>, | |
language: Option<String>, | |
#[serde(rename="type")] type_: Option<String>, | |
created: Option<DateTime<Utc>> | |
} | |
impl GistFile { | |
pub fn timestamp(&self) -> u64 { | |
match self.created { | |
Some(d) => d.timestamp() as u64, | |
None => 0 | |
} | |
} | |
} | |
#[derive(Debug, Deserialize, Serialize)] | |
struct GistCreateFile { | |
description: Option<String>, | |
public: bool, | |
files: HashMap<String, HashMap<String, String>> | |
} | |
impl GistCreateFile { | |
pub fn new(name: String, contents:String) -> Self { | |
let mut filemap : HashMap<String, HashMap<String, String>> = HashMap::new(); | |
let mut content_map : HashMap<String, String> = HashMap::new(); | |
content_map.insert("content".to_string(), contents); | |
filemap.insert(name, content_map); | |
GistCreateFile{ | |
description: Some(String::from("")), | |
public: false, | |
files: filemap | |
} | |
} | |
} | |
#[derive(Debug, Deserialize, Serialize)] | |
pub struct Gist { | |
files: Option<HashMap<String, GistFile>>, | |
id: Option<String>, | |
description: Option<String>, | |
public: bool, | |
} | |
impl Gist { | |
pub fn contents(&self) -> Option<String> { | |
let files = self.files.as_ref(); | |
if(!files.is_none()){ | |
let file = files.unwrap().values().next().unwrap(); | |
if let Some(ref url) = file.raw_url.as_ref() { | |
let mut response = reqwest::get(url.as_str()).unwrap(); | |
let txt = response.text(); | |
return convert_op!(txt); | |
} | |
} | |
None | |
} | |
pub fn timestamp(&self) -> Option<u64> { | |
Some(self.files.as_ref().unwrap().values().next().unwrap().timestamp()) | |
} | |
pub fn file(&self) -> Option<&GistFile> { | |
let files = self.files.as_ref(); | |
if(!files.is_none()){ | |
let file = files.unwrap().values().next().unwrap(); | |
Some(&file) | |
} | |
None | |
} | |
pub fn update(&self, client: GistClient, contents: String) -> Option<Self> { | |
let file = self.file(); | |
client.update_file(self.id.unwrap(), file.name , contents) | |
} | |
} | |
#[derive(Debug, Clone)] | |
pub enum GistError { | |
ClientCreationError, | |
ApiError, | |
FileNotFound | |
} | |
pub struct GistClient(Github); | |
impl GistClient { | |
pub fn new(token: String) -> Result<Self, GistError> { | |
let client = Github::new(token); | |
match client { | |
Ok(_cli) => Ok(GistClient(_cli)), | |
Err(_) => Err(GistError::ClientCreationError), | |
} | |
} | |
pub fn all_files(&self) -> Option<Vec<Gist>> { | |
let (_, _, json) = self.0.get().gists().execute::<Vec<Gist>>().unwrap(); | |
json | |
} | |
pub fn file(&self, id: String) -> Option<Gist> { | |
let (_, _, json) = self.0.get().gists().id(&id[..]).execute::<Gist>().unwrap(); | |
json | |
} | |
pub fn create_file(&self, name: String, contents: String) -> Option<Gist> { | |
let data : GistCreateFile = GistCreateFile::new(name, contents); | |
let (_, statuscode, json) = self.0.post(data).gists().execute::<Gist>().unwrap(); | |
// just for test | |
json | |
// Some(Gist{id: None, files: None, description: None, public: false}) | |
} | |
pub fn update_file(&self, id: String, name: String, contents: String) -> Option<Gist> { | |
let data: GistCreateFile = GistCreateFile::new(name, contents); | |
let (_, _, json) = self.0.patch(data).gists().id(&id[..]).execute::<Gist>().unwrap(); | |
// println!("{:?}", json); | |
// just for test | |
json | |
// Some(Gist{id: None, files: None, description: None, public: false}) | |
} | |
pub fn delete(&self, id: String) -> bool { | |
let (_, status, json) = self.0.delete(&id[..]).gists().id(&id[..]).execute::<Value>().unwrap(); | |
match status { | |
StatusCode::NoContent => true, | |
_ => false | |
} | |
} | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::{GistError, GistClient, Gist}; | |
fn get_client() -> Result<GistClient, GistError> { | |
let token: String = "f3899bdb881b5b3c5c96427b24c847300f9afee0".to_string(); | |
let client = GistClient::new(token); | |
client | |
} | |
#[test] | |
fn test_fetch_github_all_gists_for_token() { | |
let client = get_client().unwrap(); | |
let files = client.all_files(); | |
assert!(!files.is_none()); | |
} | |
#[test] | |
fn test_fetch_one_gists(){ | |
let client = get_client().unwrap(); | |
let id = "d4bc67af95883bf3f8d8602b94a29010".to_string(); | |
let file = client.file(id); | |
assert!(!file.is_none()); | |
let gist = file.unwrap(); | |
assert!(gist.contents().unwrap().len() > 0); | |
} | |
#[test] | |
#[ignore] | |
fn test_create_one_gist(){ | |
let client = get_client().unwrap(); | |
let file_name : String = "cargo-test.txt".to_string(); | |
let contents: String = "Cargo test success".to_string(); | |
let gist= client.create_file(file_name, contents); | |
assert!(!gist.is_none()); | |
} | |
#[test] | |
#[ignore] | |
fn test_delete_one_gist(){ | |
let file_id = "02bfe2dd2bee6e491c2fa406274e547e".to_string(); | |
let client = get_client().unwrap(); | |
let val = client.delete(file_id); | |
assert!(val); | |
} | |
#[test] | |
#[ignore] | |
fn test_update_one_gist(){ | |
let file_id = "70110c658769b4649a3c4375e43b8383".to_string(); | |
let client = get_client().unwrap(); | |
let file_name :String = "cargo-test.txt".to_string(); | |
let contents : String = "Cargo test success 1".to_string(); | |
let gist = client.update_file(file_id, file_name, contents); | |
assert!(!gist.is_none()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment