use serde::Deserialize;
use crate::api::client::{ApiError, GitHub, encode_path};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NewGist {
pub description: String,
pub public: bool,
pub files: Vec<(String, String)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FileChange {
pub was: String,
pub now: Option<(String, String)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GistChange {
pub id: String,
pub description: String,
pub changed: Vec<FileChange>,
pub added: Vec<(String, String)>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct MadeGist {
pub id: String,
pub owner: Option<Owner>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Owner {
pub login: String,
}
impl GitHub {
pub async fn create_gist(&self, new: &NewGist) -> Result<MadeGist, ApiError> {
let files: serde_json::Map<String, serde_json::Value> = (new.files.iter())
.map(|(name, text)| (name.clone(), serde_json::json!({ "content": text })))
.collect();
let body = serde_json::json!({
"description": new.description,
"public": new.public,
"files": files,
});
self.rest_write_json(http::Method::POST, "/gists", Some(&body))
.await
}
pub async fn update_gist(&self, change: &GistChange) -> Result<(), ApiError> {
let mut files = serde_json::Map::new();
for c in &change.changed {
let value = match &c.now {
Some((name, text)) => serde_json::json!({ "filename": name, "content": text }),
None => serde_json::Value::Null,
};
files.insert(c.was.clone(), value);
}
for (name, text) in &change.added {
files.insert(name.clone(), serde_json::json!({ "content": text }));
}
let body = serde_json::json!({ "description": change.description, "files": files });
let path = format!("/gists/{}", encode_path(&change.id));
self.rest_write(http::Method::PATCH, &path, Some(&body))
.await
}
pub async fn delete_gist(&self, id: &str) -> Result<(), ApiError> {
let path = format!("/gists/{}", encode_path(id));
self.rest_write(http::Method::DELETE, &path, None).await
}
}