shardline_protocol/lib.rs
1#![deny(unsafe_code)]
2#![cfg_attr(
3 test,
4 allow(
5 clippy::unwrap_used,
6 clippy::expect_used,
7 clippy::indexing_slicing,
8 clippy::arithmetic_side_effects,
9 clippy::shadow_unrelated,
10 clippy::let_underscore_must_use,
11 clippy::format_push_string
12 )
13)]
14
15//! Shared protocol-facing types used by Shardline clients, storage adapters, and the
16//! HTTP server.
17//!
18//! This crate keeps the wire-level contracts small and explicit:
19//!
20//! - [`ShardlineHash`] stores validated 32-byte hashes and canonical lowercase
21//! hexadecimal text.
22//! - [`ByteRange`] and [`ChunkRange`] validate range boundaries before they reach
23//! storage code.
24//! - [`TokenSigner`] signs and verifies scoped bearer tokens without exposing
25//! secret material in debug output.
26//! - [`RepositoryScope`] ties provider-issued tokens to one repository and,
27//! optionally, one revision.
28//!
29//! # Example
30//!
31//! ```
32//! use shardline_protocol::{
33//! RepositoryProvider, RepositoryScope, TokenClaims, TokenScope, TokenSigner,
34//! };
35//!
36//! let repository =
37//! RepositoryScope::new(RepositoryProvider::GitHub, "acme", "assets", Some("main"))?;
38//! let claims = TokenClaims::new(
39//! "shardline",
40//! "alice",
41//! TokenScope::Read,
42//! repository,
43//! 1_700_000_600,
44//! )?;
45//!
46//! let signer = TokenSigner::new(b"development-only-signing-key-32bytes")?;
47//! let token = signer.sign(&claims)?;
48//! let verified = signer.verify_at(&token, 1_700_000_000)?;
49//!
50//! assert_eq!(verified.subject(), "alice");
51//! assert_eq!(verified.repository().owner(), "acme");
52//! assert!(verified.scope().allows_read());
53//! # Ok::<(), Box<dyn std::error::Error>>(())
54//! ```
55
56mod hash;
57mod ranges;
58mod security;
59mod text;
60mod time;
61mod token;
62pub use hash::{HashParseError, ShardlineHash};
63pub use ranges::{ByteRange, ChunkRange, HttpRangeParseError, RangeError, parse_http_byte_range};
64pub use security::{SecretBytes, SecretString};
65pub use text::parse_bool;
66pub use time::unix_now_seconds_lossy;
67pub use token::{
68 RepositoryProvider, RepositoryScope, TokenClaims, TokenClaimsError, TokenCodecError,
69 TokenScope, TokenSigner,
70};