AimDbBuilder

Struct AimDbBuilder 

Source
pub struct AimDbBuilder<R = NoRuntime> { /* private fields */ }
Expand description

Database builder for producer-consumer pattern

Provides a fluent API for constructing databases with type-safe record registration. Use .runtime() to set the runtime and transition to a typed builder.

Implementations§

Source§

impl AimDbBuilder<NoRuntime>

Source

pub fn new() -> Self

Creates a new database builder without a runtime

Call .runtime() to set the runtime adapter.

Source

pub fn runtime<R>(self, rt: Arc<R>) -> AimDbBuilder<R>
where R: Spawn + 'static,

Sets the runtime adapter

This transitions the builder from untyped to typed with concrete runtime R.

Source§

impl<R> AimDbBuilder<R>
where R: Spawn + 'static,

Source

pub fn with_connector( self, scheme: impl Into<String>, connector: Arc<dyn Connector>, ) -> Self

Registers a connector for a specific URL scheme

The scheme (e.g., “mqtt”, “shmem”, “kafka”) determines how .link() URLs are routed. Each scheme can have ONE connector, which manages connections to a specific endpoint (broker, segment, cluster, etc.).

§Arguments
  • scheme - URL scheme without “://” (e.g., “mqtt”, “shmem”, “kafka”)
  • connector - Connector implementing the Connector trait
§Example
use aimdb_mqtt_connector::MqttConnector;
use std::sync::Arc;

let mqtt_connector = MqttConnector::new("mqtt://broker.local:1883").await?;
let shmem_connector = ShmemConnector::new("/dev/shm/aimdb");

let builder = AimDbBuilder::new()
    .runtime(runtime)
    .with_connector("mqtt", Arc::new(mqtt_connector))
    .with_connector("shmem", Arc::new(shmem_connector));

// Now .link() can route to either:
//   .link("mqtt://sensors/temp")  → mqtt_connector
//   .link("shmem://temp_data")    → shmem_connector
Source

pub fn with_remote_access(self, config: AimxConfig) -> Self

Enables remote access via AimX protocol (std only)

Configures the database to accept remote connections over a Unix domain socket, allowing external clients to introspect records, subscribe to updates, and (optionally) write data.

The remote access supervisor will be spawned automatically during build().

§Arguments
  • config - Remote access configuration (socket path, security policy, etc.)
§Example
use aimdb_core::remote::{AimxConfig, SecurityPolicy};

let config = AimxConfig::new("/tmp/aimdb.sock")
    .with_security(SecurityPolicy::read_only());

let db = AimDbBuilder::new()
    .runtime(runtime)
    .with_remote_access(config)
    .build()?;
Source

pub fn configure<T>( &mut self, f: impl for<'a> FnOnce(&'a mut RecordRegistrar<'a, T, R>), ) -> &mut Self
where T: Send + Sync + 'static + Debug + Clone,

Configures a record type manually

Low-level method for advanced use cases. Most users should use register_record instead.

Source

pub fn register_record<T>(&mut self, cfg: &T::Config) -> &mut Self
where T: RecordT<R>,

Registers a self-registering record type

The record type must implement RecordT<R>.

Source

pub async fn run(self) -> DbResult<()>

Runs the database indefinitely (never returns)

This method builds the database, spawns all producer and consumer tasks, and then parks the current task indefinitely. This is the primary way to run AimDB services.

All logic runs in background tasks via producers, consumers, and connectors. The application continues until interrupted (e.g., Ctrl+C).

§Returns

DbResult<()> - Ok when database starts successfully, then parks forever

§Example
#[tokio::main]
async fn main() -> DbResult<()> {
    AimDbBuilder::new()
        .runtime(Arc::new(TokioAdapter::new()?))
        .configure::<MyData>(|reg| {
            reg.with_buffer(BufferCfg::SpmcRing { capacity: 100 })
               .with_source(my_producer)
               .with_tap(my_consumer);
        })
        .run().await  // Runs forever
}
Source

pub fn build(self) -> DbResult<AimDb<R>>

Builds the database and returns the handle (advanced use)

Use this when you need programmatic access to the database handle for manual subscriptions or production. For typical services, use .run().await instead.

Automatic Task Spawning: This method spawns all producer services and .tap() observer tasks that were registered during configuration.

§Returns

DbResult<AimDb<R>> - The database instance

§Example
let db = AimDbBuilder::new()
    .runtime(Arc::new(TokioAdapter::new()?))
    .configure::<MyData>(|reg| { /* ... */ })
    .build()?;

// Manually subscribe or produce
let mut reader = db.subscribe::<MyData>()?;

Trait Implementations§

Source§

impl Default for AimDbBuilder<NoRuntime>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<R> Freeze for AimDbBuilder<R>

§

impl<R = NoRuntime> !RefUnwindSafe for AimDbBuilder<R>

§

impl<R> Send for AimDbBuilder<R>
where R: Send + Sync,

§

impl<R = NoRuntime> !Sync for AimDbBuilder<R>

§

impl<R> Unpin for AimDbBuilder<R>
where R: Unpin,

§

impl<R = NoRuntime> !UnwindSafe for AimDbBuilder<R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.