todoist_api/
lib.rs

1//! # Todoist-api
2//!
3//! A Rust wrapper for the Todoist REST API v2.
4//!
5//! ## Features
6//!
7//! - Async/await support
8//! - Full CRUD operations for tasks
9//! - Project and label management
10//! - Comprehensive error handling with specific error types
11//! - Rate limiting detection and retry information
12//! - Serde serialization/deserialization
13//!
14//! ## Example
15//!
16//! ```rust,no_run
17//! use todoist_api::{TodoistWrapper, TodoistError, TodoistResult};
18//! use todoist_api::models::CreateTaskArgs;
19//!
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     let todoist = TodoistWrapper::new("your-api-token".to_string());
23//!
24//!     // Get all tasks with error handling
25//!     match todoist.get_tasks().await {
26//!         Ok(tasks) => println!("Found {} tasks", tasks.len()),
27//!         Err(TodoistError::RateLimited { retry_after, message }) => {
28//!             println!("Rate limited: {} (retry after {} seconds)", message, retry_after.unwrap_or(0));
29//!         }
30//!         Err(TodoistError::AuthenticationError { message }) => {
31//!             println!("Authentication failed: {}", message);
32//!         }
33//!         Err(e) => println!("Other error: {}", e),
34//!     }
35//!
36//!     // Create a new task
37//!     let args = CreateTaskArgs {
38//!         content: "Buy groceries".to_string(),
39//!         project_id: None,
40//!         ..Default::default()
41//!     };
42//!     let new_task = todoist.create_task(&args).await?;
43//!     println!("Created task: {}", new_task.content);
44//!
45//!     Ok(())
46//! }
47//! ```
48
49pub mod models;
50pub mod wrapper;
51
52pub use models::*;
53pub use wrapper::TodoistWrapper;
54
55// Re-export commonly used types
56pub use models::{TodoistError, TodoistResult};
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn test_todoist_wrapper_creation() {
64        let _wrapper = TodoistWrapper::new("test-token".to_string());
65        // Test that the wrapper was created successfully without panicking
66        // We can't access private fields, so we just verify creation works
67        // No assertion needed - if this function completes without panic, the test passes
68    }
69
70    #[test]
71    fn test_library_exports() {
72        // Test that all main types are properly exported
73        let _task: Task = Task {
74            id: "test".to_string(),
75            content: "test".to_string(),
76            description: "test".to_string(),
77            project_id: "test".to_string(),
78            section_id: None,
79            parent_id: None,
80            order: 1,
81            priority: 1,
82            is_completed: false,
83            labels: vec![],
84            created_at: "2024-01-01T00:00:00Z".to_string(),
85            due: None,
86            deadline: None,
87            duration: None,
88            assignee_id: None,
89            url: "https://todoist.com".to_string(),
90            comment_count: 0,
91        };
92
93        let _project: Project = Project {
94            id: "test".to_string(),
95            name: "test".to_string(),
96            comment_count: 0,
97            order: 1,
98            color: "blue".to_string(),
99            is_shared: false,
100            is_favorite: false,
101            is_inbox_project: false,
102            is_team_inbox: false,
103            view_style: "list".to_string(),
104            url: "https://todoist.com".to_string(),
105            parent_id: None,
106        };
107
108        let _label: Label = Label {
109            id: "test".to_string(),
110            name: "test".to_string(),
111            color: "red".to_string(),
112            order: 1,
113            is_favorite: false,
114        };
115
116        let _wrapper: TodoistWrapper = TodoistWrapper::new("test".to_string());
117
118        // Test that Result is properly exported
119        let _result: TodoistResult<()> = Ok(());
120    }
121
122    #[test]
123    fn test_argument_types() {
124        // Test that argument types can be created and used
125        let task_args = CreateTaskArgs {
126            content: "Test task".to_string(),
127            priority: Some(3),
128            ..Default::default()
129        };
130
131        assert_eq!(task_args.content, "Test task");
132        assert_eq!(task_args.priority, Some(3));
133
134        let project_args = CreateProjectArgs {
135            name: "Test project".to_string(),
136            color: Some("blue".to_string()),
137            ..Default::default()
138        };
139
140        assert_eq!(project_args.name, "Test project");
141        assert_eq!(project_args.color, Some("blue".to_string()));
142    }
143}