Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
"examples/tokio-mqtt-connector-demo",
"examples/embassy-mqtt-connector-demo",
"examples/sync-api-demo",
"examples/remote-access-demo",
]
exclude = ["_external"]
resolver = "2"
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ test:
cargo test --package aimdb-core --no-default-features
@printf "$(YELLOW) → Testing aimdb-core (std platform)$(NC)\n"
cargo test --package aimdb-core --features "std,tracing"
@printf "$(YELLOW) → Testing aimdb-core remote module$(NC)\n"
cargo test --package aimdb-core --lib --features "std" remote::
@printf "$(YELLOW) → Testing tokio adapter$(NC)\n"
cargo test --package aimdb-tokio-adapter --features "tokio-runtime,tracing"
@printf "$(YELLOW) → Testing sync wrapper$(NC)\n"
Expand Down
2 changes: 1 addition & 1 deletion _external/embassy
17 changes: 16 additions & 1 deletion aimdb-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ build = "build.rs"
default = ["std"]

# Core capabilities
std = ["thiserror", "anyhow", "serde_json", "aimdb-executor/std"]
std = [
"serde",
"thiserror",
"anyhow",
"serde_json",
"tokio",
"aimdb-executor/std",
]

# Heap allocation in no_std environments
alloc = ["serde"] # Enable heap in no_std
Expand All @@ -35,6 +42,14 @@ thiserror = { workspace = true, optional = true }
anyhow = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }

# Async runtime - only for std environments with remote access
tokio = { workspace = true, features = [
"net",
"io-util",
"sync",
"time",
], optional = true }

# Atomic operations for all platforms
portable-atomic = { version = "1.9", default-features = false }

Expand Down
4 changes: 4 additions & 0 deletions aimdb-core/src/buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ mod traits;
pub use cfg::BufferCfg;
pub use traits::{Buffer, BufferReader, DynBuffer};

// JSON streaming support (std only)
#[cfg(feature = "std")]
pub use traits::JsonBufferReader;

// Re-export buffer-specific errors from core error module
// These are type aliases for convenience
pub use crate::DbError as BufferError;
Expand Down
36 changes: 36 additions & 0 deletions aimdb-core/src/buffer/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,42 @@ pub trait BufferReader<T: Clone + Send>: Send {
fn recv(&mut self) -> Pin<Box<dyn Future<Output = Result<T, DbError>> + Send + '_>>;
}

/// Reader trait for consuming JSON-serialized values from a buffer (std only)
///
/// Type-erased reader that subscribes to a typed buffer and emits values as
/// `serde_json::Value`. Used by remote access protocol for subscriptions.
///
/// This trait enables subscribing to a buffer without knowing the concrete type `T`
/// at compile time, by serializing values to JSON on each `recv_json()` call.
///
/// # Requirements
/// - Record must be configured with `.with_serialization()`
/// - Only available with `std` feature (requires serde_json)
///
/// # Example
/// ```rust,ignore
/// // Internal use in remote access handler
/// let json_reader: Box<dyn JsonBufferReader> = record.subscribe_json()?;
/// while let Ok(json_val) = json_reader.recv_json().await {
/// // Forward JSON value to remote client...
/// }
/// ```
#[cfg(feature = "std")]
pub trait JsonBufferReader: Send {
/// Receive the next value as JSON (async)
///
/// Waits for the next value from the underlying buffer and serializes it to JSON.
///
/// # Returns
/// - `Ok(JsonValue)` - Successfully received and serialized value
/// - `Err(BufferLagged)` - Missed messages (can continue reading)
/// - `Err(BufferClosed)` - Buffer closed (graceful shutdown)
/// - `Err(SerializationFailed)` - Failed to serialize value to JSON
fn recv_json(
&mut self,
) -> Pin<Box<dyn Future<Output = Result<serde_json::Value, DbError>> + Send + '_>>;
}

/// Blanket implementation of DynBuffer for all Buffer types
impl<T, B> DynBuffer<T> for B
where
Expand Down
Loading