Skip to content

Instantly share code, notes, and snippets.

@sourcepirate
Created January 21, 2018 04:41
Show Gist options
  • Save sourcepirate/b991bf3ed0f8682cccd19311be5834cf to your computer and use it in GitHub Desktop.
Save sourcepirate/b991bf3ed0f8682cccd19311be5834cf to your computer and use it in GitHub Desktop.
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