toggl-track 0.1.0

General-purpose async Rust library for the Toggl Track API v9
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Default, Serialize)]
pub struct UpdateTimeEntry {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub project_id: Option<Option<i64>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub billable: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tag_ids: Option<Vec<i64>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub start: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stop: Option<Option<DateTime<Utc>>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub duration: Option<i64>,
}

impl UpdateTimeEntry {
    pub fn project_id(project_id: Option<i64>) -> Self {
        Self {
            project_id: Some(project_id),
            ..Self::default()
        }
    }

    pub fn description(description: impl Into<String>) -> Self {
        Self {
            description: Some(description.into()),
            ..Self::default()
        }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct StartTimeEntry {
    pub workspace_id: i64,
    pub start: DateTime<Utc>,
    pub duration: i64,
    pub created_with: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub project_id: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub task_id: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub billable: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tag_ids: Option<Vec<i64>>,
}

impl StartTimeEntry {
    pub fn new(workspace_id: i64, created_with: impl Into<String>) -> Self {
        Self {
            workspace_id,
            start: Utc::now(),
            duration: -1,
            created_with: created_with.into(),
            description: None,
            project_id: None,
            task_id: None,
            billable: None,
            tags: None,
            tag_ids: None,
        }
    }

    pub fn description(mut self, description: impl Into<String>) -> Self {
        self.description = Some(description.into());
        self
    }

    pub fn project_id(mut self, project_id: i64) -> Self {
        self.project_id = Some(project_id);
        self
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct BulkUpdateOperation {
    pub op: String,
    pub path: String,
    pub value: serde_json::Value,
}

impl BulkUpdateOperation {
    pub fn replace(path: impl Into<String>, value: serde_json::Value) -> Self {
        Self {
            op: "replace".to_string(),
            path: path.into(),
            value,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
pub struct BulkUpdateResponse {
    #[serde(default)]
    pub success: Vec<i64>,
    #[serde(default)]
    pub failure: Vec<BulkUpdateFailure>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BulkUpdateFailure {
    pub id: i64,
    pub message: String,
}