wakapi/endpoints/projects.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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
//! Projects endpoint.
//!
//! Ref: <https://wakatime.com/developers#projects>
//!
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::{WakapiClient, WakapiError};
use super::commit::RepositoryDetails;
/// Request parameters for the Projects endpoint.
///
/// Ref: <https://wakatime.com/developers#projects>
#[derive(Serialize, Default)]
pub struct ProjectsParams {
/// optional - Filter projects by a search term
q: Option<String>,
/// optional - Page number of projects, not in documentation
page: Option<usize>,
}
impl ProjectsParams {
/// Create a new ProjectsParams with default values (no search term).
pub fn new() -> ProjectsParams {
ProjectsParams {
q: None,
page: None,
}
}
/// Set the search term parameter for the request.
pub fn q(mut self, q: &str) -> ProjectsParams {
self.q = Some(q.to_string());
self
}
/// Set the page parameter for the request.
/// This will return the projects for the given page number.
pub fn page(mut self, page: usize) -> ProjectsParams {
self.page = Some(page);
self
}
}
/// Projects endpoint.
///
/// Ref: <https://wakatime.com/developers#projects>
#[derive(Deserialize, Debug)]
pub struct Projects {
/// list of projects
pub data: Vec<ProjectsData>,
/// total number of projects
pub total: usize,
/// total number of pages
pub total_pages: usize,
/// current page number
pub page: usize,
/// previous page number
pub prev_page: Option<usize>,
/// next page number
pub next_page: Option<usize>,
}
#[derive(Deserialize, Debug)]
pub struct ProjectsData {
/// unique project id
pub id: String,
/// project name
pub name: String,
/// associated repository if connected
pub repository: Option<RepositoryDetails>,
/// associated project badge if enabled
pub badge: Option<ProjectBadge>,
/// custom project color as hex string, or null if using default color
pub color: Option<String>,
/// clients associated with this project
pub clients: Vec<ProjectClients>,
/// whether this project has a shareable url defined
pub has_public_url: bool,
/// time when project last received code stats as human readable string
pub human_readable_last_heartbeat_at: String,
/// time when project last received code stats in ISO 8601 format
pub last_heartbeat_at: DateTime<Utc>,
/// time when project first received code stats as human readable string; currently only set for users who signed up after 2024-02-05T00:00:00Z UTC
pub first_heartbeat_at: Option<String>,
/// url of this project relative to wakatime.com
pub url: String,
/// project name url entity encoded
pub urlencoded_name: String,
/// time when project was created in ISO 8601 format
pub created_at: DateTime<Utc>,
}
#[derive(Deserialize, Debug)]
pub struct ProjectBadge {
/// badge color
pub color: String,
/// badge unique id
pub id: String,
/// badge left text
pub left_text: String,
/// badge link
pub link: String,
/// badge project id
pub project_id: String,
/// badge snippets
pub snippets: Vec<BadgeSnippet>,
/// badge title
pub title: String,
/// badge url
pub url: String,
}
#[derive(Deserialize, Debug)]
pub struct BadgeSnippet {
/// snippet content
pub content: String,
/// snippet name
pub name: String,
}
#[derive(Deserialize, Debug)]
pub struct ProjectClients {
/// unique client id
pub id: String,
/// client name
pub name: String,
/// client rate
pub rate: f64,
/// client timeout
pub timeout: usize,
}
impl Projects {
/// Fetch the projects for the current user.
pub fn fetch(client: &WakapiClient, params: ProjectsParams) -> Result<Self, WakapiError> {
let url = client.build_url(
"/api/v1/users/current/projects",
Some(serde_url_params::to_string(¶ms)?),
);
// Debug, print url and response body
println!(
"url: {}\nbody: {}",
url,
reqwest::blocking::Client::new()
.get(&url)
.header("Authorization", client.get_auth_header())
.send()?
.text()?
);
let response = reqwest::blocking::Client::new()
.get(&url)
.header("Authorization", client.get_auth_header())
.send()?;
if response.status().is_success() {
let body = response.json::<Projects>()?;
Ok(body)
} else {
let error = response.json::<crate::error::ErrorMessage>()?;
Err(WakapiError::ResponseError(error))
}
}
}