api-bones 4.0.0

Opinionated REST API types: errors (RFC 9457), pagination, health checks, and more
Documentation
//! # api-bones
//!
//! Opinionated REST API types: errors (RFC 9457), pagination, health checks, and more.
//!
//! ## `no_std` support
//!
//! This crate is `#![no_std]` when the default `std` feature is disabled.
//!
//! | Features enabled         | Available types                                    |
//! |--------------------------|-----------------------------------------------------|
//! | *(none)*                 | Pure-`core` types: `ErrorCode`, `HealthStatus`, `PaginationParams`, `SortDirection` |
//! | `alloc`                  | All types that use `String`/`Vec`/`Arc`             |
//! | `std` *(default)*        | Full feature set including `HashMap`-backed types   |
//!
//! ```toml
//! # no_std + alloc (WASM, embedded with allocator)
//! api-bones = { version = "...", default-features = false, features = ["alloc"] }
//!
//! # pure no_std (core types only)
//! api-bones = { version = "...", default-features = false }
//! ```
//!
//! ## Core type: [`ApiError`]
//!
//! Every service serializes errors into [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457)
//! Problem Details format:
//!
//! ```json
//! {
//!   "type": "urn:api-bones:error:resource-not-found",
//!   "title": "Resource Not Found",
//!   "status": 404,
//!   "detail": "Booking 123 not found"
//! }
//! ```
//!
//! ```rust
//! use api_bones::{ApiError, ErrorCode};
//!
//! fn find_booking(id: u64) -> Result<(), ApiError> {
//!     Err(ApiError::not_found(format!("booking {id} not found")))
//! }
//! ```
//!
//! ## Feature flags (selection)
//!
//! | Feature    | What it enables                                      |
//! |------------|------------------------------------------------------|
//! | `schemars` | [`schemars::JsonSchema`] derive on all public types  |
//! | `utoipa`   | [`utoipa::ToSchema`] derive on all public types      |
//!
//! Enable `schemars` in your `Cargo.toml`:
//!
//! ```toml
//! api-bones = { version = "3", features = ["schemars"] }
//! ```
//!
//! ## Add as dependency
//!
//! ```toml
//! [dependencies]
//! api-bones = "3"
//! ```

#![cfg_attr(not(feature = "std"), no_std)]

// When `std` is not available but `alloc` is, bring the alloc crate into scope.
// Under `std`, the `alloc` crate is re-exported by `std` so no explicit import
// is needed.
#[cfg(all(not(feature = "std"), feature = "alloc"))]
extern crate alloc;

// Auth module: requires the `auth` feature (implies alloc + base64 + zeroize).
#[cfg(feature = "auth")]
pub mod auth;

// Modules that require heap allocation (String / Vec / Arc).
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod audit;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod bulk;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod cache;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod correlation_id;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod cors;
#[cfg(feature = "base64")]
pub mod cursor;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod deprecated;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod etag;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod header_id;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod idempotency;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod links;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod org_context;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod org_id;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod range;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod request_id;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod response;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod slug;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub mod traceparent;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod url;
#[cfg(any(feature = "std", feature = "alloc"))]
pub mod vary;
pub mod version;

// Modules available in all configurations; individual types inside are gated
// where they require `alloc` or `std`.
pub mod common;
pub mod error;
pub mod health;
pub mod method;
pub mod pagination;
pub mod query;
pub mod ratelimit;
pub mod retry;
pub mod status;

#[cfg(any(feature = "std", feature = "alloc"))]
pub mod content_type;

#[cfg(feature = "http")]
pub mod header;

#[cfg(all(feature = "serde", any(feature = "std", feature = "alloc")))]
pub mod serde;

#[cfg(feature = "fake")]
mod fake_impls;

#[cfg(feature = "icalendar")]
pub mod calendar;

// OpenAPI helpers: Example<T> and DeprecatedField (issues #119, #120).
pub mod openapi;

// Axum extractors beyond IntoResponse (issue #121).
#[cfg(feature = "axum")]
pub mod axum_extractors;

#[cfg(any(feature = "std", feature = "alloc"))]
pub use audit::{
    AuditInfo, Principal, PrincipalId, PrincipalKind, PrincipalParseError, ResolvedPrincipal,
};
#[cfg(feature = "auth")]
pub use auth::{
    ApiKeyCredentials, AuthScheme, AuthorizationHeader, BasicCredentials, BearerToken, OAuth2Token,
    ParseAuthorizationError, ParsePermissionError, ParseScopeError, Permission, Scope,
};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use bulk::{BulkItemResult, BulkRequest, BulkResponse};
#[cfg(feature = "uuid")]
pub use common::ResourceId;
#[cfg(feature = "uuid")]
pub use common::new_resource_id;
#[cfg(feature = "chrono")]
pub use common::parse_timestamp;
// Timestamp is chrono::DateTime when chrono is on (no alloc needed),
// or String when chrono is off (needs alloc or std).
#[cfg(any(feature = "std", feature = "alloc"))]
pub use cache::CacheControl;
#[cfg(any(feature = "chrono", feature = "std", feature = "alloc"))]
pub use common::Timestamp;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use content_type::ContentType;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use correlation_id::{CorrelationId, CorrelationIdError};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use cors::{CorsHeaders, CorsOrigin};
#[cfg(feature = "base64")]
pub use cursor::{Cursor, CursorError};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use deprecated::Deprecated;
pub use error::ErrorCode;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use error::ErrorTypeMode;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use error::HttpError;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "serde"))]
pub use error::ProblemJson;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use error::{ApiError, ValidationError};
#[cfg(feature = "std")]
pub use error::{error_type_mode, set_error_type_mode, urn_namespace};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use etag::{ETag, IfMatch, IfNoneMatch};
#[cfg(feature = "http")]
pub use header::{HeaderName, HeaderValue};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use header_id::HeaderId;
pub use health::HealthStatus;
#[cfg(feature = "std")]
pub use health::ReadinessResponse;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use health::{HealthCheck, LivenessResponse};
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use idempotency::{IdempotencyKey, IdempotencyKeyError};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use links::{Link, Links};
pub use method::HttpMethod;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use org_context::{
    Attestation, AttestationKind, OrganizationContext, Role, RoleBinding, RoleScope,
};
#[cfg(all(
    any(feature = "std", feature = "alloc"),
    feature = "uuid",
    feature = "http"
))]
pub use org_id::OrgIdHeaderError;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use org_id::{OrgId, OrgIdError, OrgPath};
pub use pagination::PaginationParams;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use pagination::{
    CursorPaginatedResponse, CursorPagination, CursorPaginationParams, PaginatedResponse,
};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use pagination::{KeysetPaginatedResponse, KeysetPaginationParams};
pub use query::SortDirection;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use query::{FilterEntry, FilterParams, SearchParams, SortParams};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use range::{ByteRange, ContentRange, ParseRangeError, RangeHeader};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use ratelimit::RateLimitInfo;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use request_id::{RequestId, RequestIdError, RequestIdParseError};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use response::{ApiResponse, ApiResponseBuilder, ResponseMeta};
pub use retry::{BackoffStrategy, Idempotent, RetryPolicy};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use retry::{RetryAfter, RetryAfterParseError};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use slug::{Slug, SlugError};
pub use status::StatusCode;
#[cfg(all(any(feature = "std", feature = "alloc"), feature = "uuid"))]
pub use traceparent::{SamplingFlags, SpanId, TraceContext, TraceContextError, TraceId};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use url::{QueryBuilder, UrlBuilder};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use vary::Vary;
pub use version::{ApiVersion, ApiVersionParseError, SemverTriple};