use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::{error::Error, path::PathBuf};
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct Project {
pub id: Option<String>,
pub name: Option<String>,
pub description: Option<String>,
pub created_by: Option<u64>,
pub created_date: Option<DateTime<Utc>>,
pub due_date: Option<DateTime<Utc>>,
pub public: Option<bool>,
pub members: Option<Vec<u64>>,
}
impl Project {
pub fn new() -> Self {
Project {
id: None,
name: None,
description: None,
created_by: None,
created_date: None,
due_date: None,
public: None,
members: None,
}
}
pub fn template() -> Self {
Project {
id: Some(String::from("0")),
name: Some(String::from("Project Name")),
description: Some(String::from("Project Description")),
created_by: Some(12345),
created_date: Some(Utc::now()),
due_date: Some(Utc::now()),
public: Some(true),
members: Some(vec![0, 1, 2, 3]),
}
}
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct List {
pub id: Option<u64>,
pub name: Option<String>,
#[serde(rename = "type")]
pub list_type: Option<String>,
pub index: u32,
}
impl List {
pub fn new() -> Self {
List {
id: None,
name: None,
list_type: None,
index: 0,
}
}
pub fn template() -> Self {
List {
id: Some(0),
name: Some(String::from("List Name")),
list_type: Some(String::from("")),
index: 0,
}
}
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct Task {
pub id: Option<u64>,
pub project_id: Option<u64>,
pub project_list_id: Option<u64>,
pub task_name: Option<String>,
pub description: Option<String>,
pub created_date: Option<DateTime<Utc>>,
pub due_date: Option<DateTime<Utc>>,
pub priority: Option<u32>,
pub created_by: Option<u64>,
pub owned_by: Option<u64>,
pub contributors: Option<Vec<u64>>,
pub attachment_count: Option<u32>,
pub tags: Option<Vec<String>>,
pub archived: bool,
}
impl Task {
pub fn new() -> Self {
Task {
id: None,
project_id: None,
project_list_id: None,
task_name: None,
description: None,
created_date: None,
due_date: None,
priority: None,
created_by: None,
owned_by: None,
contributors: None,
attachment_count: None,
tags: None,
archived: false,
}
}
pub fn template() -> Self {
Task {
id: Some(0),
project_id: Some(0),
project_list_id: Some(0),
task_name: Some(String::from("Task Name")),
description: Some(String::from("Task Description")),
created_date: Some(Utc::now()),
due_date: Some(Utc::now()),
priority: Some(0),
created_by: Some(27),
owned_by: Some(27),
contributors: Some(vec![0, 1, 2, 3]),
attachment_count: Some(0),
tags: Some(vec![
String::from("A"),
String::from("B"),
String::from("C"),
]),
archived: false,
}
}
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct Attachment {
pub id: Option<u32>,
pub task_id: Option<u32>,
pub created_date: Option<DateTime<Utc>>,
pub file_name: Option<String>,
pub mime_type: Option<String>,
}
#[derive(Serialize)]
struct QueryParams {
pub limit: Option<u32>,
pub offset: Option<u32>,
}
impl super::Client {
pub async fn get_projects(
&self,
limit: Option<u32>,
offset: Option<u32>,
) -> Result<Vec<Project>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let q = QueryParams { limit, offset };
let mut response = surf::get(&format!("{}{}", self.host, "/v1/projects/"))
.query(&q)?
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn post_project(
&self,
project: Project,
) -> Result<Project, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::post(&format!("{}{}", self.host, "/v1/projects"))
.header("Authorization", at)
.body(surf::Body::from_json(&project)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project(
&self,
id: &str,
) -> Result<Project, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!("{}{}{}", self.host, "/v1/projects/", id))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn put_project(
&self,
id: &str,
project: Project,
) -> Result<Project, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::put(&format!("{}{}{}", self.host, "/v1/projects/", id))
.header("Authorization", at)
.body(surf::Body::from_json(&project)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn delete_project(
&self,
id: &str,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::delete(&format!("{}{}{}", self.host, "/v1/projects/", id))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_members(
&self,
id: &str,
) -> Result<Vec<u64>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}",
self.host, "/v1/projects/", id, "/members"
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn put_project_members(
&self,
id: &str,
members: Vec<u64>,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::put(&format!(
"{}{}{}{}",
self.host, "/v1/projects/", id, "/members"
))
.header("Authorization", at)
.body(surf::Body::from_json(&members)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_lists(
&self,
id: &str,
) -> Result<Vec<List>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}",
self.host, "/v1/projects/", id, "/lists"
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn post_project_list(
&self,
project_id: &str,
list: List,
) -> Result<List, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::post(&format!(
"{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists"
))
.header("Authorization", at)
.body(surf::Body::from_json(&list)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_list(
&self,
project_id: &str,
list_id: &str,
) -> Result<List, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn put_project_list(
&self,
project_id: &str,
list_id: &str,
list: List,
) -> Result<List, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::put(&format!(
"{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id
))
.header("Authorization", at)
.body(surf::Body::from_json(&list)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn delete_project_list(
&self,
project_id: &str,
list_id: &str,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::delete(&format!(
"{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_tasks(
&self,
id: &str,
limit: Option<u32>,
offset: Option<u32>,
) -> Result<Vec<Task>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let q = QueryParams { limit, offset };
let mut response = surf::get(&format!(
"{}{}{}{}",
self.host, "/v1/projects/", id, "/tasks"
))
.query(&q)?
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_list_tasks(
&self,
project_id: &str,
list_id: &str,
limit: Option<u32>,
offset: Option<u32>,
) -> Result<Vec<Task>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let q = QueryParams { limit, offset };
let mut response = surf::get(&format!(
"{}{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id, "/tasks"
))
.query(&q)?
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn post_project_list_task(
&self,
project_id: &str,
list_id: &str,
task: Task,
) -> Result<Task, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::post(&format!(
"{}{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id, "/tasks"
))
.header("Authorization", at)
.body(surf::Body::from_json(&task)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_list_task(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
) -> Result<Task, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id, "/tasks/", task_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn put_project_list_task(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
task: Task,
) -> Result<Task, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::put(&format!(
"{}{}{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id, "/tasks/", task_id
))
.header("Authorization", at)
.body(surf::Body::from_json(&task)?)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn delete_project_list_task(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::delete(&format!(
"{}{}{}{}{}{}{}",
self.host, "/v1/projects/", project_id, "/lists/", list_id, "/tasks/", task_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_list_task_attachments(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
) -> Result<Vec<Attachment>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}{}{}{}{}",
self.host,
"/v1/projects/",
project_id,
"/lists/",
list_id,
"/tasks/",
task_id,
"/attachments"
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn get_project_list_task_attachment(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
attachment_id: &str,
) -> Result<Vec<u8>, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::get(&format!(
"{}{}{}{}{}{}{}{}{}",
self.host,
"/v1/projects/",
project_id,
"/lists/",
list_id,
"/tasks/",
task_id,
"/attachments/",
attachment_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_bytes().await?)
}
pub async fn post_project_list_task_attachment(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
_path: PathBuf,
) -> Result<Attachment, Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::post(&format!(
"{}{}{}{}{}{}{}{}",
self.host,
"/v1/projects/",
project_id,
"/lists/",
list_id,
"/tasks/",
task_id,
"/attachments"
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
pub async fn delete_project_list_task_attachment(
&self,
project_id: &str,
list_id: &str,
task_id: &str,
attachment_id: &str,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let at = self.get_access_token("workflow").await?;
let mut response = surf::delete(&format!(
"{}{}{}{}{}{}{}{}{}",
self.host,
"/v1/projects/",
project_id,
"/lists/",
list_id,
"/tasks/",
task_id,
"/attachments/",
attachment_id
))
.header("Authorization", at)
.await?;
if !response.status().is_success() {
let e: Box<super::PubAPIError> = response.body_json().await?;
return Err(e);
}
Ok(response.body_json().await?)
}
}