Skip to main content

aimdb_core/
lib.rs

1//! AimDB Core Database Engine
2//!
3//! # aimdb-core
4//!
5//! Type-safe, async in-memory database for data synchronization
6//! across MCU → edge → cloud environments.
7//!
8//! # Architecture
9//!
10//! - **RecordKey/RecordId**: Stable identifiers for multi-instance records
11//! - **Runtime Agnostic**: Works with Tokio (std) or Embassy (embedded)
12//! - **Producer-Consumer**: Built-in typed message passing
13//!
14//! See examples in the repository for usage patterns.
15//!
16//! # A panic is a bug, not an error channel
17//!
18//! Every failure is a [`DbError`]. The crate is compiled under
19//! `deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)` outside its
20//! tests; the sites that remain carry an `allow` with a reason. A dependency
21//! can still panic on its own, and a poisoned lock is recovered from.
22//!
23//! # Where aimdb's own reporting goes
24//!
25//! Two optional destinations, neither on by default: **`tracing`**, the ordinary
26//! choice for a Rust binary, and **`log`**, for a host that cannot be handed a
27//! process-global subscriber — chiefly an FFI layer, which needs its callback's
28//! context pointer to live somewhere a `tracing::Layer` has no room for. Both
29//! may be on at once; both off emits nothing. Events carry the emitting module
30//! as their target (`aimdb_core::builder`) either way.
31//! Every crate in this workspace that reports at all now does so through the
32//! facade, so a destination sees the connectors too. See
33//! [docs/design/050](https://github.com/aimdb-dev/aimdb/blob/main/docs/design/050-log-destination-for-ffi.md)
34//! for filtering and duplicate delivery.
35//!
36//! ## What a `log` destination must guarantee
37//!
38//! Getting one wrong costs a deadlock or memory unsafety, not a bad log line:
39//!
40//! 1. **Called from any thread**, aimdb's runtime thread included.
41//! 2. **Must not unwind** — across a C or C++ boundary that is UB.
42//! 3. **Must not re-enter aimdb on a path that itself logs.** `log` has no
43//!    reentrancy guard (`tracing` does), so this recurses without bound.
44//!    Getters are fine.
45//! 4. **Must not block on anything a thread might hold while calling into
46//!    aimdb** — that is the lock ordering.
47//! 5. **Cannot be uninstalled.** `set_logger` is once per process; a second
48//!    call returns `Err` and the first destination keeps receiving.
49
50// A panic here is a bug: two FFI doors sit above this crate, and a consumer's
51// `panic = "abort"` compiles their guard out.
52#![cfg_attr(
53    not(test),
54    deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)
55)]
56#![cfg_attr(not(feature = "std"), no_std)]
57
58extern crate alloc;
59
60// Must precede the other modules: `macro_rules!` visibility is textual.
61#[macro_use]
62mod log;
63
64/// Implementation detail of the `log_*` macros; no stability guarantee.
65///
66/// The macros expand in the *calling* crate, so they can only name paths
67/// reachable from there — this re-export is what saves a facade user from
68/// declaring `log` itself.
69#[doc(hidden)]
70pub mod __private {
71    // `::log`, not `log`: this crate has a private `log` module at its root.
72    #[cfg(feature = "log")]
73    pub use ::log;
74    #[cfg(feature = "tracing")]
75    pub use ::tracing;
76}
77
78pub mod buffer;
79pub mod builder;
80#[cfg(feature = "remote")]
81pub mod codec;
82pub mod connector;
83pub mod context;
84mod error;
85pub mod executor;
86pub mod extensions;
87pub mod graph;
88#[cfg(feature = "observability")]
89pub mod profiling;
90pub mod record_id;
91#[cfg(feature = "remote")]
92pub mod remote;
93pub mod router;
94#[cfg(feature = "connector-session")]
95pub mod session;
96pub mod signal;
97pub mod transform;
98pub mod transport;
99pub mod typed_api;
100pub mod typed_record;
101
102// Public API exports
103pub use context::RuntimeContext;
104pub use error::{ConfigError, DbError, DbErrorKind, DbResult};
105pub use extensions::Extensions;
106
107// Runtime capability surface: the runtime travels as `Arc<dyn RuntimeOps>`,
108// the one trait an adapter implements.
109pub use executor::{BoxFuture, ExecutorError, ExecutorResult, LogLevel, RuntimeOps};
110
111// Producer-Consumer Pattern exports
112#[cfg(feature = "remote")]
113pub use buffer::JsonReader;
114pub use buffer::Reader;
115pub use buffer::TryProduceError;
116pub use builder::OutboundRoute;
117pub use builder::{AimDb, AimDbBuilder};
118pub use connector::ConnectorBuilder;
119pub use transport::{Connector, ConnectorConfig, PublishError};
120pub use typed_api::{
121    Consumer, InboundConnectorBuilder, OutboundConnectorBuilder, Producer, RecordRegistrar,
122    StageKind,
123};
124#[cfg(feature = "remote")]
125pub use typed_record::JsonRecordAccess;
126pub use typed_record::{AnyRecord, AnyRecordExt, TypedRecord};
127
128// JSON codec (feature `remote`, no_std + alloc compatible)
129#[cfg(feature = "remote")]
130pub use codec::{JsonCodec, RemoteSerialize, SerdeJsonCodec};
131
132// Record-key leaf/entity derivation, shared by record metadata and the
133// connectors that surface the `entity` field.
134#[cfg(feature = "remote")]
135pub use remote::topic_leaf;
136
137// connector-session contracts (feature `connector-session`, no_std + alloc
138// compatible). See docs/design/remote-access-via-connectors.md.
139#[cfg(feature = "connector-session")]
140pub use session::{
141    is_wildcard, pattern_contains, pump_sink, pump_source, topic_matches, AuthError, BoxFut,
142    BoxStream, CodecError, Connection, Dialer, Dispatch, EnvelopeCodec, Inbound, Listener,
143    Outbound, Payload, PeerInfo, RpcError, SessionCtx, SessionLimits, Source, SubUpdate,
144    TransportError, TransportResult,
145};
146
147// Signal gauge handle (always available; inert without `observability`)
148pub use signal::SignalGaugeHandle;
149
150// Stage profiling exports (feature-gated)
151#[cfg(feature = "observability")]
152pub use profiling::{
153    RecordProfilingMetrics, SignalGauge, SignalStats, SignalStatsInfo, StageMetrics,
154    StageProfilingInfo,
155};
156
157// Connector Infrastructure exports
158pub use connector::TopicProvider;
159pub use connector::TopicResolverFn;
160pub use connector::{ConnectorLink, ConnectorUrl, LinkAddress, SerializeError};
161pub use connector::{IngestFactoryFn, IngestFn};
162pub use connector::{
163    SerializedPayload, SerializedReader, SerializedSource, SerializedValue, SerializedValueInto,
164    SourceFactoryFn,
165};
166
167// Router exports for connector implementations
168pub use router::{Route, Router, RouterBuilder};
169
170// Record identification exports
171pub use record_id::{RecordId, RecordKey, StringKey};
172
173// Graph exports (dependency graph for record topology)
174pub use graph::{DependencyGraph, EdgeType, GraphEdge, GraphNode, RecordOrigin};
175
176// Transform API exports
177pub use transform::{JoinBuilder, JoinEventRx, JoinPipeline, JoinTrigger};
178pub use transform::{TransformBuilder, TransformPipeline};