Skip to main content

haste_document_storage/
lib.rs

1//! Storage for document bodies (Binary content, attachments, exports) that is
2//! independent of the hosting cloud.
3//!
4//! Callers only use the [`DocumentStorage`] trait; each backend lives under
5//! [`providers`] behind a cargo feature and is built with [`connect`].
6//!
7//! ```no_run
8//! use haste_document_storage::{
9//!     Document, DocumentKey, DocumentStorageKind, StorageError,
10//!     providers::gcs::{GcsConfig, GcsCredentials},
11//! };
12//!
13//! # async fn example() -> Result<(), StorageError> {
14//! let storage = haste_document_storage::connect(DocumentStorageKind::Gcs(GcsConfig {
15//!     bucket: "my-bucket".into(),
16//!     prefix: Some("documents".into()),
17//!     credentials: GcsCredentials::ApplicationDefault,
18//!     endpoint: None,
19//! }))
20//! .await?;
21//!
22//! let key = DocumentKey::new("tenant/project/Binary/123")?;
23//! storage
24//!     .put(&key, Document::new(b"...".as_slice()).with_content_type("application/pdf"))
25//!     .await?;
26//! let document = storage.get(&key).await?;
27//! let bytes = document.body.collect().await?;
28//! # Ok(())
29//! # }
30//! ```
31
32mod error;
33mod traits;
34mod types;
35
36pub mod providers;
37pub mod retry;
38
39use std::sync::Arc;
40
41pub use error::StorageError;
42pub use traits::{DocumentStorage, StorageFuture};
43pub use types::{
44    Document, DocumentBody, DocumentKey, DocumentMetadata, ListPage, ListRequest, StoredDocument,
45};
46
47/// The backend to connect to, with its configuration.
48#[derive(Debug)]
49pub enum DocumentStorageKind {
50    #[cfg(feature = "gcs")]
51    Gcs(providers::gcs::GcsConfig),
52}
53
54/// Builds the configured backend and verifies that it can authenticate.
55///
56/// # Errors
57///
58/// Returns [`StorageError::Configuration`] or [`StorageError::Unauthorized`]
59/// when the backend cannot be set up or its credentials are rejected.
60pub async fn connect(kind: DocumentStorageKind) -> Result<Arc<dyn DocumentStorage>, StorageError> {
61    match kind {
62        #[cfg(feature = "gcs")]
63        DocumentStorageKind::Gcs(config) => Ok(Arc::new(
64            providers::gcs::GcsDocumentStorage::connect(config).await?,
65        )),
66    }
67}