Add Outline API client library foundation
Implements a first vertical slice of the Outline RPC API (auth, documents, collections, users) covering the structural patterns used across the whole API: single object, paginated list, tree, create/update, delete, search. Chosen as the basis for future CLI and GUI clients built on top of this crate. - Handwritten client (not codegen) against the vendored OpenAPI spec, since Outline's API is uniformly POST /api/<resource>.<action> with JSON bodies and inline/anonymous schemas that generators handle poorly - Async (reqwest + tokio) Client, cheaply cloneable, no &mut self methods - thiserror-based Error with ErrorKind classification and boxed API error context; forward-compatible models (unknown fields ignored, unknown string-enum values preserved via a catch-all variant) since the API is unversioned and self-hosted instances vary in age - Pagination via Page<T>/Paginator with next_page/collect_all/into_stream - wiremock-based test suite plus a spec-coverage test guarding against typos in RPC method names
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::common::{Id, Permission, Timestamp, UnknownVariant};
|
||||
use super::user::User;
|
||||
|
||||
/// A collection: a top-level grouping of documents in Outline.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[non_exhaustive]
|
||||
pub struct Collection {
|
||||
/// Unique identifier for the collection.
|
||||
pub id: Id,
|
||||
/// The relative URL path at which the collection can be accessed.
|
||||
#[serde(default)]
|
||||
pub url: Option<String>,
|
||||
/// A short unique identifier that can be used in place of the UUID.
|
||||
#[serde(default)]
|
||||
pub url_id: Option<String>,
|
||||
/// The name of the collection.
|
||||
pub name: String,
|
||||
/// A description of the collection, may contain markdown formatting.
|
||||
#[serde(default)]
|
||||
pub description: Option<String>,
|
||||
/// The position of the collection in the sidebar.
|
||||
#[serde(default)]
|
||||
pub index: Option<String>,
|
||||
/// A color representing the collection, in `#RRGGBB` format.
|
||||
#[serde(default)]
|
||||
pub color: Option<String>,
|
||||
/// An icon name or emoji associated with the collection.
|
||||
#[serde(default)]
|
||||
pub icon: Option<String>,
|
||||
/// The sharing permission level for this collection.
|
||||
#[serde(default)]
|
||||
pub permission: Option<Permission>,
|
||||
/// Whether public document sharing is enabled in this collection.
|
||||
#[serde(default)]
|
||||
pub sharing: bool,
|
||||
/// Whether commenting is enabled in this collection.
|
||||
#[serde(default)]
|
||||
pub commenting: Option<bool>,
|
||||
/// The date and time this collection was created.
|
||||
#[serde(default)]
|
||||
pub created_at: Option<Timestamp>,
|
||||
/// The date and time this collection was last changed.
|
||||
#[serde(default)]
|
||||
pub updated_at: Option<Timestamp>,
|
||||
/// The date and time this collection was archived, if applicable.
|
||||
#[serde(default)]
|
||||
pub archived_at: Option<Timestamp>,
|
||||
/// The user who archived this collection, if applicable.
|
||||
#[serde(default)]
|
||||
pub archived_by: Option<User>,
|
||||
}
|
||||
|
||||
/// The status a collection may be filtered by in `collections.list`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[non_exhaustive]
|
||||
pub enum CollectionStatus {
|
||||
/// The collection has been archived.
|
||||
Archived,
|
||||
/// A value not recognized by this version of the crate.
|
||||
#[serde(untagged)]
|
||||
Unknown(UnknownVariant),
|
||||
}
|
||||
Reference in New Issue
Block a user