cloudconvert_sdk/lib.rs
1//! Async Rust SDK primitives for the CloudConvert API v2.
2//!
3//! This crate exposes typed request and response models for CloudConvert jobs
4//! and tasks, plus a [`CloudConvertClient`] for calling the API from async Rust
5//! applications. Operation-specific drift is handled through `option(...)`
6//! builder methods, `extra` maps, and [`TaskRequest::custom`].
7//!
8//! # Build jobs
9//!
10//! Use [`JobCreateRequest::linear`] when each task feeds into the next task.
11//!
12//! ```
13//! use cloudconvert_sdk::{FileExtension, JobCreateRequest};
14//!
15//! let request = JobCreateRequest::linear()
16//! .import_url("https://example.test/input.docx")
17//! .convert(FileExtension::Pdf)
18//! .export_url()
19//! .build();
20//!
21//! let payload = serde_json::to_value(request).unwrap();
22//! assert_eq!(payload["tasks"]["import-url"]["operation"], "import/url");
23//! assert_eq!(payload["tasks"]["convert"]["input"], "import-url");
24//! assert_eq!(payload["tasks"]["export-url"]["input"], "convert");
25//! ```
26//!
27//! Use `*_with(...)` methods to configure task-specific options while keeping a
28//! serial pipeline.
29//!
30//! ```
31//! use cloudconvert_sdk::{FileExtension, JobCreateRequest};
32//!
33//! let request = JobCreateRequest::linear()
34//! .import_url_with("https://example.test/input.docx", |task| {
35//! task.filename("input.docx")
36//! })
37//! .convert_with(FileExtension::Pdf, |task| {
38//! task.input_format(FileExtension::Docx)
39//! })
40//! .export_url()
41//! .build();
42//!
43//! let payload = serde_json::to_value(request).unwrap();
44//! assert_eq!(payload["tasks"]["import-url"]["filename"], "input.docx");
45//! assert_eq!(payload["tasks"]["convert"]["input_format"], "docx");
46//! ```
47//!
48//! Use [`JobCreateRequest::graph`] when a job branches, joins multiple inputs,
49//! or needs to reference a non-adjacent task.
50//!
51//! ```
52//! use cloudconvert_sdk::{FileExtension, JobCreateRequest};
53//!
54//! let request = JobCreateRequest::graph(|job| {
55//! let import = job.import_url("https://example.test/input.docx");
56//! let pdf = job.convert(&import, FileExtension::Pdf);
57//! let png = job.convert(&import, FileExtension::Png);
58//! job.export_url([&pdf, &png]);
59//! })
60//! .build();
61//!
62//! let payload = serde_json::to_value(request).unwrap();
63//! assert_eq!(payload["tasks"]["convert"]["input"], "import-url");
64//! assert_eq!(payload["tasks"]["convert-2"]["input"], "import-url");
65//! assert_eq!(
66//! payload["tasks"]["export-url"]["input"],
67//! serde_json::json!(["convert", "convert-2"])
68//! );
69//! ```
70//!
71//! # Call the API
72//!
73//! Live API calls need a CloudConvert API key. `ApiKey::from_env()` reads
74//! `CLOUDCONVERT_API_KEY`.
75//!
76//! ```no_run
77//! use cloudconvert_sdk::{ApiKey, CloudConvertClient, FileExtension, JobCreateRequest};
78//!
79//! # async fn run() -> cloudconvert_sdk::Result<()> {
80//! let client = CloudConvertClient::builder(ApiKey::from_env()?).build()?;
81//! let request = JobCreateRequest::linear()
82//! .import_url("https://example.test/input.docx")
83//! .convert(FileExtension::Pdf)
84//! .export_url()
85//! .build();
86//!
87//! let job = client.jobs().create(request).await?;
88//! let finished = client.jobs().wait(&job.id).await?;
89//! for file in finished.export_urls() {
90//! if let Some(url) = &file.url {
91//! let bytes = client.download(url).await?;
92//! println!("downloaded {} bytes as {}", bytes.len(), file.filename);
93//! }
94//! }
95//! # Ok(())
96//! # }
97//! ```
98
99mod client;
100mod config;
101mod error;
102mod file_extension;
103mod jobs;
104mod oauth;
105mod operations;
106mod resources;
107mod signed_url;
108mod socket;
109mod tasks;
110mod webhook;
111
112pub use client::{
113 CloudConvertClient, JobsResource, OperationsResource, TasksResource, UsersResource,
114 WebhooksResource,
115};
116#[cfg(feature = "retry")]
117pub use config::RetryPolicy;
118pub use config::{
119 ApiKey, ClientBuilder, CloudConvertConfig, OAuthAccessToken, OAuthClientSecret,
120 OAuthRefreshToken, Region, SigningSecret, TransportConfig,
121};
122pub use error::{ApiError, Error, Result};
123pub use file_extension::{FileExtension, ParseFileExtensionError};
124pub use jobs::{
125 ApiResponse, FileResult, Job, JobBuilder, JobCreateRequest, JobGetQuery, JobGraphBuilder,
126 JobListQuery, JobStatus, JobTask, Page, PaginationLinks, PaginationMeta, RateLimit, Task,
127 TaskGetQuery, TaskListQuery, TaskName, TaskResult, TaskStatus, UploadForm,
128};
129pub use oauth::{OAuthClient, OAuthScope, OAuthTokenResponse};
130pub use operations::{
131 Operation, OperationEngineVersion, OperationListQuery, OperationOption, OperationOptionKind,
132 OperationValidationError, OperationValidationErrorKind, OperationValidationMode,
133 OperationValidationResult,
134};
135pub use resources::{User, Webhook, WebhookCreateRequest, WebhookEvent, WebhookListQuery};
136pub use signed_url::sign_job_url;
137#[cfg(feature = "socket")]
138pub use socket::{CloudConvertSocket, SocketEvent};
139pub use socket::{
140 JobSocketEvent, SocketChannel, SocketEventKind, SocketSubscription, TaskSocketEvent,
141 socket_base_url,
142};
143pub use tasks::{
144 ArchiveTask, AzureBlobExportTask, AzureBlobImportTask, Base64ImportTask, CaptureWebsiteTask,
145 CommandTask, ConvertTask, ExportUploadTask, ExportUrlTask, ExtraOptions, FontAlign,
146 GenericTask, GoogleCloudStorageExportTask, GoogleCloudStorageImportTask, ImportUploadTask,
147 ImportUrlTask, Input, Layer, MergeTask, MetadataTask, MetadataWriteTask, OpenStackExportTask,
148 OpenStackImportTask, OptimizeTask, PdfATask, PdfDecryptTask, PdfEncryptTask,
149 PdfExtractPagesTask, PdfOcrTask, PdfRotatePagesTask, PdfSplitPagesTask, PdfXTask,
150 PositionHorizontal, PositionVertical, RawImportTask, S3ExportTask, S3ImportTask,
151 SftpExportTask, SftpImportTask, TaskPayload, TaskRequest, ThumbnailTask, WatermarkTask,
152};
153pub use webhook::{sign_payload, verify_signature};