1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! `reliar-core` is the pure envelope/message model every Reliar crate builds on: identity
//! newtypes, the [`Message`] contract, a validated [`Headers`] map, typed [`Metadata`], and the
//! [`Envelope`]/[`SerializedEnvelope`] pair that carries them. It has no storage or transport
//! dependency of its own — no sqlx, no broker client, no routing concept (a Kafka partition key,
//! a `RabbitMQ` exchange, a NATS subject) — so it is useful standalone, as the shared vocabulary
//! two independent Reliar crates (say an outbox and a transport) use to talk to each other, or as
//! a typed envelope model for an application that does not use the rest of Reliar at all.
//!
//! # The types you touch
//!
//! - [`Message`] — implement this on your own type to give it a stable, renaming-proof identity
//! (`TYPE` + `VERSION`), never derived from `std::any::type_name::<T>()` or a module path.
//! - [`Envelope<T>`] / [`SerializedEnvelope`] — the same generic type on both sides of
//! serialization: an `Envelope<YourType>` on the way in, `Envelope<bytes::Bytes>` once a
//! [`Serializer`] has turned the body to bytes. Build one with [`Envelope::builder`].
//! - [`Metadata`] — canonical, typed framework metadata (correlation, trace, routing, delivery,
//! tenant). One source of truth: a value here is never duplicated into [`Headers`], and Reliar
//! never reads a framework value back out of headers.
//! - [`Headers`] — your own custom, application-defined metadata. A validating newtype, not a
//! bare map: it rejects the entire `reliar-` prefix case-insensitively, so a custom header can
//! never collide with — or be mistaken for — a framework one.
//! - [`Serializer`] (default impl: [`JsonSerializer`], behind the default `json` feature) —
//! converts a typed body to and from bytes.
//! - [`Publisher`] — the trait a transport implements to send an envelope; paired with
//! [`Classify`]/[`FailureKind`] so a caller can tell a retryable failure from a permanent one
//! without inspecting transport internals.
//! - [`uuid_id!`]/[`uuid_id_serde!`] — declare a UUID-backed identity newtype (`from_uuid`/
//! `as_uuid`, optional minting/`Default`/`serde`) in any crate; paired with the re-exported
//! [`mod@uuid`] so the generated signatures name one `Uuid` type everywhere.
//!
//! # End to end
//!
//! `JsonSerializer` ships behind the default `json` feature; without it this block still shows
//! the shape but is not compiled (`cargo test --doc --no-default-features` would not see
//! `JsonSerializer`/`JsonError`).
//! use reliar_core::{Envelope, JsonSerializer, Message, Serializer};
//!
//! #[derive(serde::Serialize, serde::Deserialize)]
//! struct OrderCreated {
//! order_id: u64,
//! }
//!
//! impl Message for OrderCreated {
//! const TYPE: &'static str = "orders.created";
//! const VERSION: u16 = 1;
//! }
//!
//! // Build a typed envelope; `message_type` and the conversation root are derived, not chosen.
//! let envelope = Envelope::builder(OrderCreated { order_id: 42 })
//! .tenant("acme")
//! .build();
//! assert_eq!(envelope.message_type.to_string(), "orders.created.v1");
//!
//! // Serialize the body; the serialized envelope is what storage/transport crates see.
//! let serializer = JsonSerializer;
//! let bytes = serializer.serialize(&envelope.body)?;
//! let serialized = envelope.map_body(|_| bytes);
//! assert_eq!(serialized.metadata.tenant_id.as_deref(), Some("acme"));
//! # Ok::<(), reliar_core::JsonError>(())
//! ```
//!
//! Every public error is a hand-rolled, `#[non_exhaustive]` enum with a wired
//! [`std::error::Error::source`] — no `thiserror`, no `anyhow`. `Debug` on payload-bearing types
//! elides the bytes; no `Display` here ever prints a payload, a header value, or a credential.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use EnvelopeMapper;
pub use ;
pub use ;
pub use Publisher;
pub use Serializer;
pub use SettingsError;
/// Re-exported so a [`uuid_id!`] invocation and its generated `from_uuid`/`as_uuid` signatures
/// name **this** `Uuid`, whichever crate declares the id (ADR 0045) — a caller needs no `uuid`
/// dependency of its own to interoperate with an id `reliar-core` declares.
pub use uuid;
pub use ;
// The crate README's only fenced Rust block is the `JsonSerializer` quickstart; gate the whole
// module on `json` rather than editing static markdown to carry a per-block cfg_attr.