From 90457155aaa0ea54d0d5c84a29b0e037086e14ff Mon Sep 17 00:00:00 2001 From: Joshua Coles Date: Sat, 2 Mar 2024 10:10:30 +0000 Subject: [PATCH] Refactor Toggl API types Significant renaming and data type changes to Toggl API types occurred to improve identification and consistency. For example, 'Current' is renamed to 'TimeEntry', 'ProjectClient' is renamed to 'Client', and 'TogglQuery' is renamed to 'TogglReportQuery'. Changes affected multiple sections of the codebase, including routes and DB access. --- src/db.rs | 4 ++-- src/poll.rs | 8 ++++---- src/routes.rs | 14 +++++++------- src/toggl_api/api_client.rs | 12 ++++++------ src/toggl_api/types.rs | 29 +++++++++++++++++++---------- 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/db.rs b/src/db.rs index b34c03a..d963b70 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,5 +1,5 @@ use crate::entity::{client, project, time_entry}; -use crate::toggl_api::types::{Project, ProjectClient, ReportRow}; +use crate::toggl_api::types::{Project, Client, ReportRow}; use sea_orm::sea_query::OnConflict; use sea_orm::{NotSet, Set}; @@ -32,7 +32,7 @@ impl ReportRow { } } -impl ProjectClient { +impl Client { pub fn as_model(&self) -> client::ActiveModel { client::ActiveModel { id: Set(self.id), diff --git a/src/poll.rs b/src/poll.rs index ecdd430..6fae87a 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -1,6 +1,6 @@ use crate::toggl_api::TogglApiClient; use crate::entity::{client, project}; -use crate::toggl_api::types::{Project, ProjectClient, TogglQuery}; +use crate::toggl_api::types::{Project, Client, TogglReportQuery}; use sea_orm::{DatabaseConnection, EntityTrait, QuerySelect}; use tracing::instrument; use crate::utils; @@ -42,7 +42,7 @@ pub async fn perform_poll( .to_string(); let report = client - .full_report(&TogglQuery { + .full_report(&TogglReportQuery { start_date: Some(today_string.clone()), end_date: Some(today_string.clone()), ..Default::default() @@ -64,8 +64,8 @@ pub async fn perform_poll( if new_projects { let clients = client.fetch_clients().await?; - client::Entity::insert_many(clients.iter().map(ProjectClient::as_model)) - .on_conflict(ProjectClient::grafting_conflict_statement()) + client::Entity::insert_many(clients.iter().map(Client::as_model)) + .on_conflict(Client::grafting_conflict_statement()) .exec(db) .await?; diff --git a/src/routes.rs b/src/routes.rs index 7e7951d..7f738b8 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -12,7 +12,7 @@ use chrono::{NaiveDate}; use serde::Deserialize; use crate::entity::time_entry::{Entity as TimeEntry}; use crate::toggl_api::TogglApiClient; -use crate::toggl_api::types::{Current, Project, ProjectClient, ReportRow, TogglQuery}; +use crate::toggl_api::types::{self, Project, Client, ReportRow, TogglReportQuery}; use crate::{entity, utils}; use crate::entity::time_entry; @@ -20,7 +20,7 @@ use crate::entity::time_entry; pub async fn report( Extension(toggl_client): Extension, Extension(db): Extension, - Json(query): Json, + Json(query): Json, ) -> utils::Result>> { let report = toggl_client.full_report(&query).await?; debug!("Returned results: {:?}", report); @@ -73,7 +73,7 @@ pub async fn cache_report( #[instrument(skip(toggl_client))] pub async fn current( Extension(toggl_client): Extension, -) -> utils::Result>> { +) -> utils::Result>> { Ok(toggl_client.fetch_current_time_entry().await.map(Json)?) } @@ -106,10 +106,10 @@ pub async fn projects( pub async fn clients( Extension(db): Extension, Extension(toggl_client): Extension, -) -> utils::Result>> { +) -> utils::Result>> { let clients = toggl_client.fetch_clients().await?; - entity::client::Entity::insert_many(clients.iter().map(ProjectClient::as_model)) - .on_conflict(ProjectClient::grafting_conflict_statement()) + entity::client::Entity::insert_many(clients.iter().map(Client::as_model)) + .on_conflict(Client::grafting_conflict_statement()) .exec(&db) .await?; @@ -161,7 +161,7 @@ pub async fn refresh( let start_date_query_string = start_date.unwrap_or(end_date_query_string.clone()); let start_date = NaiveDate::parse_from_str(&start_date_query_string, "%Y-%m-%d")?; - let query = TogglQuery { + let query = TogglReportQuery { start_date: Some(start_date_query_string), end_date: Some(end_date_query_string), ..Default::default() diff --git a/src/toggl_api/api_client.rs b/src/toggl_api/api_client.rs index 1784d6b..b775c3c 100644 --- a/src/toggl_api/api_client.rs +++ b/src/toggl_api/api_client.rs @@ -10,7 +10,7 @@ use hyper::HeaderMap; use reqwest::header::HeaderValue; use tracing::instrument; use tracing::log::debug; -use crate::toggl_api::types::{Current, Project, ProjectClient, ReportRow, TogglQuery}; +use crate::toggl_api::types::{TimeEntry, Project, Client as ProjectClient, ReportRow, TogglReportQuery}; #[derive(Debug, Clone)] pub struct TogglApiClient { @@ -100,7 +100,7 @@ impl TogglApiClient { Ok(clients) } - pub async fn fetch_current_time_entry(&self) -> crate::Result> { + pub async fn fetch_current_time_entry(&self) -> crate::Result> { let url = format!( "{base_url}/me/time_entries/current", base_url = self.base_url @@ -110,14 +110,14 @@ impl TogglApiClient { .client .get(url)) .await? - .json::>() + .json::>() .await?; Ok(res) } - fn paginate_filters(original_filters: &TogglQuery, last_row_id: u64) -> TogglQuery { - let mut filters: TogglQuery = original_filters.clone(); + fn paginate_filters(original_filters: &TogglReportQuery, last_row_id: u64) -> TogglReportQuery { + let mut filters: TogglReportQuery = original_filters.clone(); filters.first_row_number = Some(last_row_id + 1); filters } @@ -125,7 +125,7 @@ impl TogglApiClient { #[instrument(skip(self, filters))] pub async fn full_report( &self, - filters: &TogglQuery, + filters: &TogglReportQuery, ) -> anyhow::Result> { let url = format!( "{base_url}/workspace/{workspace_id}/search/time_entries", diff --git a/src/toggl_api/types.rs b/src/toggl_api/types.rs index d757952..4cf412d 100644 --- a/src/toggl_api/types.rs +++ b/src/toggl_api/types.rs @@ -30,19 +30,28 @@ pub struct ReportRowInnerTimeEntry { pub at: String, } -#[derive(Debug, Serialize, Deserialize)] -pub struct Current { - pub id: u64, - pub workspace_id: u64, - pub project_id: Option, - pub task_id: Option, +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TimeEntry { + pub id: i64, + pub workspace_id: i64, + pub project_id: Option, + pub task_id: Option, pub billable: bool, pub start: String, pub stop: Option, pub duration: i64, pub description: String, pub tags: Vec, - pub tag_ids: Vec, + pub tag_ids: Vec, + pub at: String, + pub server_deleted_at: Option, + pub user_id: i64, + + // Ignored fields + // duronly: bool, + // uid: i64, + // wid: i64, + // pid: Option, } #[derive(Debug, Serialize, Deserialize)] @@ -59,7 +68,7 @@ pub struct Project { /// Represents a client in Toggl. #[derive(Debug, Serialize, Deserialize)] -pub struct ProjectClient { +pub struct Client { /// Indicates whether the client is archived or not. pub archived: bool, @@ -81,7 +90,7 @@ pub struct ProjectClient { #[skip_serializing_none] #[derive(Serialize, Deserialize, Clone, Default)] -pub struct TogglQuery { +pub struct TogglReportQuery { pub billable: Option, pub client_ids: Option>, pub description: Option, @@ -115,7 +124,7 @@ pub struct TogglQuery { use std::fmt; -impl fmt::Debug for TogglQuery { +impl fmt::Debug for TogglReportQuery { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut ds = f.debug_struct("TogglQuery");