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
|
//! # A Pure Rust Library for the [Trakt.tv](https://trakt.tv) API
//!
//! [](https://crates.io/crates/trakt-rs)
//! [](https://docs.rs/trakt-rs)
//! 
//! [](https://github.com/ansg191/trakt/actions/workflows/rust.yml)
//! [](https://codecov.io/gh/ansg191/trakt)
//!
//! Trakt.tv API Documentation: [https://trakt.docs.apiary.io](https://trakt.docs.apiary.io)
//!
//! ## Usage
//!
//! This library does not provide a client for making HTTP(s) requests.
//! That is left to the user. This enables the user to use any HTTP client they prefer
//! (e.g. `reqwest`, `hyper`, `isahc`, etc.) with any TLS backend (e.g. `native-tls`, `rustls`, etc.)
//! in a synchronous or asynchronous manner.
//!
//! Instead, the library provides a set of request and response types that can be converted into the
//! general purpose [`http::Request`] and [`http::Response`] types.
//! The types fill out the entirety of the HTTP request, including the URL, headers, and body.
//! However, the user may still modify the request before sending it.
//!
//! The advantage of this approach is that the user has infinite flexibility in how they make requests.
//! They can use any HTTP client, any TLS backend, and any request/response handling mechanism.
//! Additionally, the user is free to make modifications to the request before sending it or the
//! response after receiving it.
//!
//! This also means this library has a smaller dependency tree, as it does not depend on
//! runtime or HTTP client libraries.
//!
//! ### Example
//!
//! ```no_run
//! use trakt_rs::{Request, Response};
//!
//! // Context required for all requests
//! let ctx = trakt_rs::Context {
//! base_url: "https://api.trakt.tv",
//! client_id: "client_id",
//! oauth_token: None,
//! };
//!
//! // Create a request and convert it into an HTTP request
//! let req = trakt_rs::api::movies::summary::Request {
//! id: trakt_rs::smo::Id::Imdb("tt123456".into()),
//! };
//! let http_req: http::Request<Vec<u8>> = req.try_into_http_request(ctx).unwrap();
//!
//! // Send the HTTP request using your preferred HTTP client
//! let response = http::Response::new(vec![]);
//!
//! // Convert the HTTP response into a Trakt response
//! let trakt_response = trakt_rs::api::movies::summary::Response::try_from_http_response(response).unwrap();
//!
//! println!("Movie: {:?}", trakt_response.0);
//! ```
#![warn(
clippy::pedantic,
clippy::nursery,
clippy::cargo,
clippy::as_underscore,
clippy::clone_on_ref_ptr,
clippy::format_push_string,
clippy::mod_module_files,
clippy::str_to_string
)]
#![allow(clippy::module_name_repetitions, clippy::redundant_pub_crate)]
pub mod api;
pub mod smo;
#[cfg(test)]
mod test;
pub use trakt_core::{
error, AuthRequirement, Context, EmojiString, Metadata, PaginatedResponse, Pagination,
PaginationResponse, Request, Response,
};
time::serde::format_description!(iso8601_date, Date, "[year]-[month]-[day]");
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use time::{Date, Month};
use super::*;
#[test]
fn test_iso8601_date() {
#[derive(Debug, Serialize, Deserialize)]
struct TestDate {
#[serde(with = "iso8601_date")]
date: Date,
}
let date = TestDate {
date: Date::from_calendar_date(2021, Month::December, 31).unwrap(),
};
let json = serde_json::to_string(&date).unwrap();
assert_eq!(json, r#"{"date":"2021-12-31"}"#);
let date = TestDate {
date: Date::from_calendar_date(2024, Month::April, 1).unwrap(),
};
let json = serde_json::to_string(&date).unwrap();
assert_eq!(json, r#"{"date":"2024-04-01"}"#);
let json = r#"{"date":"2024-04-01"}"#;
let date: TestDate = serde_json::from_str(json).unwrap();
assert_eq!(
date.date,
Date::from_calendar_date(2024, Month::April, 1).unwrap()
);
}
}
|