Skip to main content

uor_addr/sexp/
pipeline.rs

1//! `sexp::address` — the S-expression realization's public entry point.
2//!
3//! 1. [`SExprCanon::validate`] checks the S-expression grammar at the
4//!    host boundary (UTF-8, balanced parentheses, single top-level value)
5//!    over the borrowed input — no buffer, no caps.
6//! 2. [`AddressModel::forward`] runs the shared ψ-tower: the borrowed
7//!    [`SExprCanon`] flows in as an ADR-060 `Stream` carrier that emits
8//!    Rivest canonical bytes on demand, and ψ₉ folds them chunk-by-chunk
9//!    through `H = Sha256Hasher` to mint the κ-label.
10//! 3. [`AddressOutcome::from_grounded`] extracts the owned κ-label +
11//!    replayable TC-05 witness.
12
13pub use crate::outcome::{AddressOutcome, AddressWitness, VerifyError};
14
15/// Failure modes from [`address`].
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum AddressFailure {
18    /// The input bytes were not a valid UTF-8 S-expression.
19    InvalidSExpr,
20    /// Defensive: foundation's catamorphism or a resolver returned a
21    /// shape violation. Unreachable for well-formed inputs.
22    PipelineFailure,
23}
24
25use crate::sexp::model::{
26    AddressModel, AddressModelBlake3, AddressModelKeccak256, AddressModelSha3_256,
27    AddressModelSha512,
28};
29use crate::sexp::value::{SExprCanon, SExprValue};
30use prism::pipeline::PrismModel;
31
32/// **uor-addr's sexp entry point** (σ-axis `Sha256Hasher`) — one
33/// ψ-pipeline content-address inference, yielding a `sha256:<64hex>`
34/// κ-label.
35///
36/// # Errors
37///
38/// - [`AddressFailure::InvalidSExpr`] — the input is not well-formed.
39/// - [`AddressFailure::PipelineFailure`] — defensive; unreachable.
40pub fn address(input_bytes: &[u8]) -> Result<AddressOutcome<71>, AddressFailure> {
41    SExprCanon::validate(input_bytes).map_err(|_| AddressFailure::InvalidSExpr)?;
42    let canon = SExprCanon::new(input_bytes);
43    let grounded = AddressModel::forward(SExprValue::new(&canon))
44        .map_err(|_| AddressFailure::PipelineFailure)?;
45    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
46}
47
48/// The sexp entry point under σ-axis `Blake3Hasher` — yields a
49/// `blake3:<64hex>` κ-label. See [`address`] for the error contract.
50///
51/// # Errors
52///
53/// As [`address`].
54pub fn address_blake3(input_bytes: &[u8]) -> Result<AddressOutcome<71>, AddressFailure> {
55    SExprCanon::validate(input_bytes).map_err(|_| AddressFailure::InvalidSExpr)?;
56    let canon = SExprCanon::new(input_bytes);
57    let grounded = AddressModelBlake3::forward(SExprValue::new(&canon))
58        .map_err(|_| AddressFailure::PipelineFailure)?;
59    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
60}
61
62/// The sexp entry point under σ-axis `Sha3_256Hasher` — yields a
63/// `sha3-256:<64hex>` κ-label. See [`address`] for the error contract.
64///
65/// # Errors
66///
67/// As [`address`].
68pub fn address_sha3_256(input_bytes: &[u8]) -> Result<AddressOutcome<73>, AddressFailure> {
69    SExprCanon::validate(input_bytes).map_err(|_| AddressFailure::InvalidSExpr)?;
70    let canon = SExprCanon::new(input_bytes);
71    let grounded = AddressModelSha3_256::forward(SExprValue::new(&canon))
72        .map_err(|_| AddressFailure::PipelineFailure)?;
73    AddressOutcome::<73>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
74}
75
76/// The sexp entry point under σ-axis `Keccak256Hasher` — yields a
77/// `keccak256:<64hex>` κ-label. See [`address`] for the error contract.
78///
79/// # Errors
80///
81/// As [`address`].
82pub fn address_keccak256(input_bytes: &[u8]) -> Result<AddressOutcome<74>, AddressFailure> {
83    SExprCanon::validate(input_bytes).map_err(|_| AddressFailure::InvalidSExpr)?;
84    let canon = SExprCanon::new(input_bytes);
85    let grounded = AddressModelKeccak256::forward(SExprValue::new(&canon))
86        .map_err(|_| AddressFailure::PipelineFailure)?;
87    AddressOutcome::<74>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
88}
89
90/// The sexp entry point under σ-axis `Sha512Hasher` — yields a
91/// `sha512:<128hex>` κ-label (135 bytes, 64-byte fingerprint). See
92/// [`address`] for the error contract.
93///
94/// # Errors
95///
96/// As [`address`].
97pub fn address_sha512(input_bytes: &[u8]) -> Result<AddressOutcome<135, 64>, AddressFailure> {
98    SExprCanon::validate(input_bytes).map_err(|_| AddressFailure::InvalidSExpr)?;
99    let canon = SExprCanon::new(input_bytes);
100    let grounded = AddressModelSha512::forward(SExprValue::new(&canon))
101        .map_err(|_| AddressFailure::PipelineFailure)?;
102    AddressOutcome::<135, 64>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
103}