Skip to main content

uor_addr/xml/
pipeline.rs

1//! `xml::address` — the XML realization's public entry point.
2//!
3//! 1. [`canonicalize`] parses + emits
4//!    the W3C XML-C14N 1.1 (subset) canonical form into an `alloc` buffer
5//!    (no width / count caps).
6//! 2. `AddressModel::forward` runs the shared ψ-tower: the canonical
7//!    bytes flow in as an ADR-060 `Borrowed` carrier and ψ₉ folds them
8//!    through `H = Sha256Hasher` to mint the κ-label.
9//! 3. [`AddressOutcome::from_grounded`] extracts the owned κ-label +
10//!    replayable TC-05 witness.
11//!
12//! XML canonicalization requires heap storage (attribute sort scratch +
13//! canonical output), so [`address`] is gated behind the `alloc` feature.
14
15pub use crate::outcome::{AddressOutcome, AddressWitness, VerifyError};
16
17/// Failure modes from [`address`].
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum AddressFailure {
20    /// The input bytes were not a well-formed XML document in the
21    /// supported canonical-XML subset.
22    InvalidXml,
23    /// Defensive: foundation's catamorphism or a resolver returned a
24    /// shape violation. Unreachable for well-formed inputs.
25    PipelineFailure,
26}
27
28#[cfg(feature = "alloc")]
29use crate::xml::model::{
30    AddressModel, AddressModelBlake3, AddressModelKeccak256, AddressModelSha3_256,
31    AddressModelSha512,
32};
33#[cfg(feature = "alloc")]
34use crate::xml::value::{canonicalize, XmlValue};
35#[cfg(feature = "alloc")]
36use prism::pipeline::PrismModel;
37
38/// **uor-addr's xml entry point** (σ-axis `Sha256Hasher`) — one
39/// ψ-pipeline content-address inference, yielding a `sha256:<64hex>`
40/// κ-label.
41///
42/// # Errors
43///
44/// - [`AddressFailure::InvalidXml`] — the input is not well-formed.
45/// - [`AddressFailure::PipelineFailure`] — defensive; unreachable.
46#[cfg(feature = "alloc")]
47pub fn address(input_bytes: &[u8]) -> Result<AddressOutcome<71>, AddressFailure> {
48    let canonical = canonicalize(input_bytes).map_err(|_| AddressFailure::InvalidXml)?;
49    let grounded = AddressModel::forward(XmlValue::new(&canonical))
50        .map_err(|_| AddressFailure::PipelineFailure)?;
51    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
52}
53
54/// The xml entry point under σ-axis `Blake3Hasher` — yields a
55/// `blake3:<64hex>` κ-label. See [`address`] for the error contract.
56///
57/// # Errors
58///
59/// As [`address`].
60#[cfg(feature = "alloc")]
61pub fn address_blake3(input_bytes: &[u8]) -> Result<AddressOutcome<71>, AddressFailure> {
62    let canonical = canonicalize(input_bytes).map_err(|_| AddressFailure::InvalidXml)?;
63    let grounded = AddressModelBlake3::forward(XmlValue::new(&canonical))
64        .map_err(|_| AddressFailure::PipelineFailure)?;
65    AddressOutcome::<71>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
66}
67
68/// The xml entry point under σ-axis `Sha3_256Hasher` — yields a
69/// `sha3-256:<64hex>` κ-label. See [`address`] for the error contract.
70///
71/// # Errors
72///
73/// As [`address`].
74#[cfg(feature = "alloc")]
75pub fn address_sha3_256(input_bytes: &[u8]) -> Result<AddressOutcome<73>, AddressFailure> {
76    let canonical = canonicalize(input_bytes).map_err(|_| AddressFailure::InvalidXml)?;
77    let grounded = AddressModelSha3_256::forward(XmlValue::new(&canonical))
78        .map_err(|_| AddressFailure::PipelineFailure)?;
79    AddressOutcome::<73>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
80}
81
82/// The xml entry point under σ-axis `Keccak256Hasher` — yields a
83/// `keccak256:<64hex>` κ-label. See [`address`] for the error contract.
84///
85/// # Errors
86///
87/// As [`address`].
88#[cfg(feature = "alloc")]
89pub fn address_keccak256(input_bytes: &[u8]) -> Result<AddressOutcome<74>, AddressFailure> {
90    let canonical = canonicalize(input_bytes).map_err(|_| AddressFailure::InvalidXml)?;
91    let grounded = AddressModelKeccak256::forward(XmlValue::new(&canonical))
92        .map_err(|_| AddressFailure::PipelineFailure)?;
93    AddressOutcome::<74>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
94}
95
96/// The xml entry point under σ-axis `Sha512Hasher` — yields a
97/// `sha512:<128hex>` κ-label (135 bytes, 64-byte fingerprint). See
98/// [`address`] for the error contract.
99///
100/// # Errors
101///
102/// As [`address`].
103#[cfg(feature = "alloc")]
104pub fn address_sha512(input_bytes: &[u8]) -> Result<AddressOutcome<135, 64>, AddressFailure> {
105    let canonical = canonicalize(input_bytes).map_err(|_| AddressFailure::InvalidXml)?;
106    let grounded = AddressModelSha512::forward(XmlValue::new(&canonical))
107        .map_err(|_| AddressFailure::PipelineFailure)?;
108    AddressOutcome::<135, 64>::from_grounded(&grounded).map_err(|_| AddressFailure::PipelineFailure)
109}