Skip to content
Open
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
342 changes: 338 additions & 4 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ jsonpath-rust = "1.0.4"
# Lazy static values
once_cell = "1.19"

# ORM
sea-orm = { version = "1", features = ["sqlx-sqlite", "runtime-tokio-rustls"] }

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This SQLite-only integration pulls SeaORM's default datatype features, adding several unused dependency trees and avoidable compile cost. Disabling defaults and explicitly retaining macros keeps the derive-based entities working with a smaller dependency surface.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Cargo.toml, line 323:

<comment>This SQLite-only integration pulls SeaORM's default datatype features, adding several unused dependency trees and avoidable compile cost. Disabling defaults and explicitly retaining `macros` keeps the derive-based entities working with a smaller dependency surface.</comment>

<file context>
@@ -319,6 +319,9 @@ jsonpath-rust = "1.0.4"
 once_cell = "1.19"
 
+# ORM
+sea-orm = { version = "1", features = ["sqlx-sqlite", "runtime-tokio-rustls"] }
+
 # ============================================
</file context>
Fix with cubic


# ============================================
# Build Profiles
# ============================================
Expand Down
81 changes: 47 additions & 34 deletions crates/mcb-application/src/use_cases/indexing_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Instant;

use ignore::WalkBuilder;
use mcb_domain::constants::{INDEXING_STATUS_COMPLETED, INDEXING_STATUS_STARTED};
use mcb_domain::error::Result;
use mcb_domain::events::DomainEvent;
use mcb_domain::ports::{
ContextServiceInterface, EventBusProvider, FileHashRepository, IndexingOperationsInterface,
IndexingResult, IndexingServiceInterface, IndexingStatus, LanguageChunkingProvider,
ContextServiceInterface, EventBusProvider, FileHashRepository, FileSystemProvider,
IndexingOperationsInterface, IndexingResult, IndexingServiceInterface, IndexingStatus,
LanguageChunkingProvider, TaskRunnerProvider,
};
use mcb_domain::value_objects::{CollectionId, OperationId};
use tracing::{error, info, warn};
Expand Down Expand Up @@ -102,11 +102,14 @@ pub struct IndexingServiceImpl {
language_chunker: Arc<dyn LanguageChunkingProvider>,
indexing_ops: Arc<dyn IndexingOperationsInterface>,
event_bus: Arc<dyn EventBusProvider>,
file_system_provider: Arc<dyn FileSystemProvider>,
task_runner_provider: Arc<dyn TaskRunnerProvider>,
file_hash_repository: Option<Arc<dyn FileHashRepository>>,
supported_extensions: Vec<String>,
}

/// `IndexingServiceDeps` struct.
#[allow(missing_docs)]
pub struct IndexingServiceDeps {
/// Service for Context operations
pub context_service: Arc<dyn ContextServiceInterface>,
Expand All @@ -116,6 +119,8 @@ pub struct IndexingServiceDeps {
pub indexing_ops: Arc<dyn IndexingOperationsInterface>,
/// Event bus
pub event_bus: Arc<dyn EventBusProvider>,
pub file_system_provider: Arc<dyn FileSystemProvider>,
pub task_runner_provider: Arc<dyn TaskRunnerProvider>,
/// Supported file extensions
pub supported_extensions: Vec<String>,
}
Expand All @@ -139,13 +144,17 @@ impl IndexingServiceImpl {
language_chunker: Arc<dyn LanguageChunkingProvider>,
indexing_ops: Arc<dyn IndexingOperationsInterface>,
event_bus: Arc<dyn EventBusProvider>,
file_system_provider: Arc<dyn FileSystemProvider>,
task_runner_provider: Arc<dyn TaskRunnerProvider>,
supported_extensions: Vec<String>,
) -> Self {
Self {
context_service,
language_chunker,
indexing_ops,
event_bus,
file_system_provider,
task_runner_provider,
file_hash_repository: None,
supported_extensions: Self::normalize_supported_extensions(supported_extensions),
}
Expand All @@ -163,6 +172,8 @@ impl IndexingServiceImpl {
language_chunker: service.language_chunker,
indexing_ops: service.indexing_ops,
event_bus: service.event_bus,
file_system_provider: service.file_system_provider,
task_runner_provider: service.task_runner_provider,
file_hash_repository: Some(file_hash_repository),
supported_extensions: Self::normalize_supported_extensions(
service.supported_extensions,
Expand All @@ -185,31 +196,32 @@ impl IndexingServiceImpl {
progress: &mut IndexingProgress,
) -> Vec<std::path::PathBuf> {
let mut files = Vec::new();
let walker = WalkBuilder::new(path)
.hidden(false)
.filter_entry(|entry| {
if !entry.file_type().is_some_and(|ft| ft.is_dir()) {
return true;
}

entry
.file_name()
.to_str()
.is_none_or(|name| !SKIP_DIRS.contains(&name))
})
.build();

for entry_result in walker {
match entry_result {
Ok(entry) => {
if entry.file_type().is_some_and(|ft| ft.is_file())
&& self.is_supported_file(entry.path())
{
files.push(entry.path().to_path_buf());
let mut dirs = vec![path.to_path_buf()];

while let Some(dir) = dirs.pop() {
match self.file_system_provider.read_dir_entries(&dir).await {

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Files excluded by .gitignore, .ignore, or Git exclude rules are now indexed because this raw directory traversal only checks the four names in SKIP_DIRS. That can ingest generated/vendor files and content users deliberately excluded from the repository (including ignored secrets), increasing index size and potentially exposing unintended content. The provider-based discovery should preserve the prior WalkBuilder ignore semantics, either through an ignore-aware filesystem API or equivalent filtering here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-application/src/use_cases/indexing_service.rs, line 202:

<comment>Files excluded by `.gitignore`, `.ignore`, or Git exclude rules are now indexed because this raw directory traversal only checks the four names in `SKIP_DIRS`. That can ingest generated/vendor files and content users deliberately excluded from the repository (including ignored secrets), increasing index size and potentially exposing unintended content. The provider-based discovery should preserve the prior `WalkBuilder` ignore semantics, either through an ignore-aware filesystem API or equivalent filtering here.</comment>

<file context>
@@ -185,31 +196,32 @@ impl IndexingServiceImpl {
+        let mut dirs = vec![path.to_path_buf()];
+
+        while let Some(dir) = dirs.pop() {
+            match self.file_system_provider.read_dir_entries(&dir).await {
+                Ok(entries) => {
+                    for entry in entries {
</file context>
Fix with cubic

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A single unreadable or concurrently removed entry now causes every sibling in that directory to be omitted from indexing. Because read_dir_entries collapses entry-level failures into one directory-level error, this loop cannot continue past the bad entry as the previous walker did. Consider returning per-entry results or making the provider retain valid entries while reporting individual failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-application/src/use_cases/indexing_service.rs, line 202:

<comment>A single unreadable or concurrently removed entry now causes every sibling in that directory to be omitted from indexing. Because `read_dir_entries` collapses entry-level failures into one directory-level error, this loop cannot continue past the bad entry as the previous walker did. Consider returning per-entry results or making the provider retain valid entries while reporting individual failures.</comment>

<file context>
@@ -185,31 +196,32 @@ impl IndexingServiceImpl {
+        let mut dirs = vec![path.to_path_buf()];
+
+        while let Some(dir) = dirs.pop() {
+            match self.file_system_provider.read_dir_entries(&dir).await {
+                Ok(entries) => {
+                    for entry in entries {
</file context>
Fix with cubic

Ok(entries) => {
for entry in entries {
if entry.is_dir {
let should_skip = entry
.path
.file_name()
.and_then(|n| n.to_str())
.is_some_and(|name| SKIP_DIRS.contains(&name));

if !should_skip {
dirs.push(entry.path);
}
continue;
}

if entry.is_file && self.is_supported_file(&entry.path) {
files.push(entry.path);
}
Comment on lines +199 to +220

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

8. Indexing loses ignore filtering 🐞 Bug ➹ Performance

discover_files now performs a manual directory traversal and only skips directories listed in
SKIP_DIRS, which removes ignore-aware walking behavior from the previous approach. This can cause
indexing to traverse and embed many additional files (generated/vendor/etc.), increasing runtime and
index noise.
Agent Prompt
### Issue description
`IndexingServiceImpl::discover_files` now walks the filesystem via `read_dir_entries` and filters only by `SKIP_DIRS` + extension. Any previous ignore-aware behavior (e.g., ignore files / repo ignore rules) is no longer applied during traversal.

### Issue Context
`SKIP_DIRS` is a fixed list and cannot cover repo-specific ignore needs.

### Fix Focus Areas
- crates/mcb-application/src/use_cases/indexing_service.rs[192-226]
- crates/mcb-application/src/constants.rs[22-24]

### Suggested fix approaches
- Reintroduce an ignore-aware walker (e.g., `ignore` crate) for traversal, while still using `FileSystemProvider` for file reads.
- Alternatively, extend `FileSystemProvider` with an ignore-aware walking API (provider-specific implementation can use `ignore::WalkBuilder` for local FS).
- Ensure traversal continues to honor `SKIP_DIRS` in addition to ignore rules.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

}
}
Err(e) => {
progress.record_error("Failed to read directory entry", path, e);
progress.record_error("Failed to read directory entries", &dir, e);
}
}
}
Expand Down Expand Up @@ -286,10 +298,14 @@ impl IndexingServiceInterface for IndexingServiceImpl {

// Fire-and-forget: caller gets operation_id immediately, polling for completion.
// Sync execution path available via run_indexing_task() directly in tests.
let _handle = tokio::spawn(async move {
let task = Box::pin(async move {
Self::run_indexing_task(service, files, workspace_root, collection_id, op_id).await;
});

if let Err(e) = self.task_runner_provider.spawn(task) {
warn!("Failed to spawn indexing background task: {}", e);
}
Comment on lines +305 to +307

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: When TaskRunnerProvider::spawn returns Err, the caller still receives a successful started result while the operation remains active forever and no indexing occurs. Cleaning up the operation and propagating the spawn error keeps polling state and the API result truthful.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-application/src/use_cases/indexing_service.rs, line 305:

<comment>When `TaskRunnerProvider::spawn` returns `Err`, the caller still receives a successful `started` result while the operation remains active forever and no indexing occurs. Cleaning up the operation and propagating the spawn error keeps polling state and the API result truthful.</comment>

<file context>
@@ -286,10 +298,14 @@ impl IndexingServiceInterface for IndexingServiceImpl {
             Self::run_indexing_task(service, files, workspace_root, collection_id, op_id).await;
         });
 
+        if let Err(e) = self.task_runner_provider.spawn(task) {
+            warn!("Failed to spawn indexing background task: {}", e);
+        }
</file context>
Suggested change
if let Err(e) = self.task_runner_provider.spawn(task) {
warn!("Failed to spawn indexing background task: {}", e);
}
if let Err(e) = self.task_runner_provider.spawn(task) {
self.indexing_ops.complete_operation(&operation_id);
return Err(e);
}
Fix with cubic


// Return immediately with operation_id
Ok(IndexingResult {
files_processed: 0,
Expand Down Expand Up @@ -424,19 +440,16 @@ impl IndexingServiceImpl {
.update_progress(operation_id, Some(relative_path.clone()), index);

// Read file content
let content = std::fs::read_to_string(file_path)
.map_err(|e| mcb_domain::error::Error::internal(format!("Failed to read file: {e}")))?;
let content = self.file_system_provider.read_to_string(file_path).await?;

// Incremental check using file hashes
let current_hash = mcb_domain::utils::compute_content_hash(&content);
#[allow(clippy::collapsible_if)]
if let Some(repo) = &self.file_hash_repository {
if !repo
if let Some(repo) = &self.file_hash_repository
&& !repo
.has_changed(&collection.to_string(), &relative_path, &current_hash)
.await?
{
return Ok(ProcessResult::Skipped);
}
{
return Ok(ProcessResult::Skipped);
}

// Generate semantic chunks
Expand Down
2 changes: 0 additions & 2 deletions crates/mcb-domain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ futures = { workspace = true }
# Plugin registration
linkme = { workspace = true }

# HTTP Client types for providers
reqwest = { workspace = true }
toml = { workspace = true, optional = true }

[features]
Expand Down
24 changes: 24 additions & 0 deletions crates/mcb-domain/src/entities/api_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,27 @@ crate::define_entity! {
pub revoked_at: Option<i64>,
}
}

crate::impl_table_schema!(ApiKey, "api_keys",
columns: [
("id", Text, pk),
("user_id", Text),
("org_id", Text),
("key_hash", Text),
("name", Text),
("scopes_json", Text),
("expires_at", Integer, nullable),
("created_at", Integer),
("revoked_at", Integer, nullable),
],
indexes: [
"idx_api_keys_user" => ["user_id"],
"idx_api_keys_org" => ["org_id"],
"idx_api_keys_key_hash" => ["key_hash"],
],
foreign_keys: [
("user_id", "users", "id"),

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: An API key can be persisted under one organization while referencing a user from another, because these independent foreign keys validate existence but not the user/org relationship. Consider enforcing (user_id, org_id) against the user's organization (or deriving org_id through users) to preserve the tenant boundary.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-domain/src/entities/api_key.rs, line 48:

<comment>An API key can be persisted under one organization while referencing a user from another, because these independent foreign keys validate existence but not the user/org relationship. Consider enforcing `(user_id, org_id)` against the user's organization (or deriving `org_id` through `users`) to preserve the tenant boundary.</comment>

<file context>
@@ -26,3 +26,27 @@ crate::define_entity! {
+        "idx_api_keys_key_hash" => ["key_hash"],
+    ],
+    foreign_keys: [
+        ("user_id", "users", "id"),
+        ("org_id", "organizations", "id"),
+    ],
</file context>
Fix with cubic

("org_id", "organizations", "id"),
],
unique_constraints: [],
);
Comment on lines +30 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add schema-sync coverage for ApiKey.

This adds columns, indexes, and foreign keys without a corresponding ApiKey::table_def()/Schema::definition() assertion. Add a test covering the table, indexes, and both foreign keys.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mcb-domain/src/entities/api_key.rs` around lines 30 - 52, Add
schema-sync test coverage for the ApiKey table definition, asserting the
expected table columns, indexes, and both user_id and org_id foreign keys
through ApiKey::table_def() or Schema::definition(). Follow the existing schema
assertion pattern and ensure the test detects drift in all declared ApiKey
schema elements.

Source: Coding guidelines

14 changes: 14 additions & 0 deletions crates/mcb-domain/src/entities/organization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,17 @@ pub enum OrgStatus {
}

crate::impl_as_str_from_as_ref!(OrgStatus);

crate::impl_table_schema!(Organization, "organizations",
columns: [
("id", Text, pk),
("name", Text),
("slug", Text, unique),
("settings_json", Text),
("created_at", Integer),
("updated_at", Integer),
],
indexes: [
"idx_organizations_name" => ["name"],
],
);
38 changes: 38 additions & 0 deletions crates/mcb-domain/src/entities/team.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,41 @@ pub enum TeamMemberRole {
}

crate::impl_as_str_from_as_ref!(TeamMemberRole);

crate::impl_table_schema!(Team, "teams",
columns: [
("id", Text, pk),
("org_id", Text),
("name", Text),
("created_at", Integer),
],
indexes: [
"idx_teams_org" => ["org_id"],
],
foreign_keys: [
("org_id", "organizations", "id"),
],
unique_constraints: [
["org_id", "name"],
],
);

crate::impl_table_schema!(TeamMember, "team_members",
columns: [
("team_id", Text, pk),
("user_id", Text, pk),
("role", Text),
("joined_at", Integer),
],
indexes: [
"idx_team_members_team" => ["team_id"],
"idx_team_members_user" => ["user_id"],
],
foreign_keys: [
("team_id", "teams", "id"),
("user_id", "users", "id"),
],
unique_constraints: [
["team_id", "user_id"],
],
);
Comment on lines +80 to +98

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd schema.rs crates/mcb-domain/src/macros
fd schema_entity_sync_tests.rs crates/mcb-domain
cat -n crates/mcb-domain/src/macros/schema.rs 2>/dev/null | sed -n '1,200p'
cat -n crates/mcb-domain/tests/unit/schema_entity_sync_tests.rs 2>/dev/null | sed -n '1,200p'

Repository: marlonsc/mcb

Length of output: 16450


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files 'crates/mcb-domain/src/entities/team.rs' 'crates/mcb-domain/src/entities/*.rs' 'crates/mcb-domain/src/schema/**' 'crates/mcb-domain/src/schema.rs' 'crates/mcb-domain/tests/unit/schema_entity_sync_tests.rs' 'crates/mcb-domain/src/macros/schema.rs'

echo "== team.rs outline =="
ast-grep outline crates/mcb-domain/src/entities/team.rs || true

echo "== team.rs relevant =="
cat -n crates/mcb-domain/src/entities/team.rs | sed -n '1,220p'

echo "== schema entity sync tests =="
cat -n crates/mcb-domain/tests/unit/schema_entity_sync_tests.rs | sed -n '1,360p'

echo "== Schema and HasTableSchema usages =="
rg -n "struct Schema|impl Schema|fn definition|HasTableSchema|impl_table_schema|team_members|TeamMember" crates/mcb-domain/src crates/mcb-domain/tests/unit/schema_entity_sync_tests.rs

Repository: marlonsc/mcb

Length of output: 21238


Add an explicit test allowance for computed schema fields.

TeamMember::id is derived from team_id:user_id and intentionally has no team_members column. Since entity-owned schema metadata is now the source of truth, add/expand schema_entity_sync_tests.rs with an explicit exemption for computed/non-persisted fields so future schema/entity sync runs don’t treat this as a drift failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mcb-domain/src/entities/team.rs` around lines 80 - 98, Update
schema_entity_sync_tests.rs to explicitly exempt computed or non-persisted
entity fields from schema synchronization checks, including TeamMember::id
derived from team_id and user_id. Preserve validation for all persisted fields
while ensuring this intentional field is not reported as schema drift.

24 changes: 24 additions & 0 deletions crates/mcb-domain/src/entities/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,27 @@ pub enum UserRole {
}

crate::impl_as_str_from_as_ref!(UserRole);

crate::impl_table_schema!(User, "users",
columns: [
("id", Text, pk),
("org_id", Text),
("email", Text),
("display_name", Text),
("role", Text),
("api_key_hash", Text, nullable),
("created_at", Integer),
("updated_at", Integer),
],
indexes: [
"idx_users_org" => ["org_id"],
"idx_users_email" => ["email"],
"idx_users_api_key_hash" => ["api_key_hash"],
],
foreign_keys: [
("org_id", "organizations", "id"),
],
unique_constraints: [
["org_id", "email"],

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Upgraded databases still permit duplicate (org_id, email) rows and orphaned org_ids because these declarations only affect newly created tables, while migrate_and_verify_schema validates columns only. Consider migrating/verifying constraints or forcing a controlled rebuild before accepting the existing schema.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-domain/src/entities/user.rs, line 74:

<comment>Upgraded databases still permit duplicate `(org_id, email)` rows and orphaned `org_id`s because these declarations only affect newly created tables, while `migrate_and_verify_schema` validates columns only. Consider migrating/verifying constraints or forcing a controlled rebuild before accepting the existing schema.</comment>

<file context>
@@ -50,3 +50,27 @@ pub enum UserRole {
+        ("org_id", "organizations", "id"),
+    ],
+    unique_constraints: [
+        ["org_id", "email"],
+    ],
+);
</file context>
Fix with cubic

],
);
41 changes: 41 additions & 0 deletions crates/mcb-domain/src/macros/di.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// Generates `Arc`-cloning getter methods for DI container fields.

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Getter generation is duplicated across all four parsing arms, so future signature, documentation, or body changes can easily diverge between aliases and list endings. A private @getter helper arm plus one comma-separated entry parser would centralize the generated method.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-domain/src/macros/di.rs, line 16:

<comment>Getter generation is duplicated across all four parsing arms, so future signature, documentation, or body changes can easily diverge between aliases and list endings. A private `@getter` helper arm plus one comma-separated entry parser would centralize the generated method.</comment>

<file context>
@@ -0,0 +1,41 @@
+        $crate::arc_getters! { $($rest)* }
+    };
+
+    ($name:ident : $ty:ty => $field:ident $(= $impl:ty)? $(,)?) => {
+        #[doc = concat!("Get `", stringify!($name), "`.")]
+        #[must_use]
</file context>
Fix with cubic

#[macro_export]
macro_rules! arc_getters {
() => {};

($name:ident : $ty:ty => $field:ident $(= $impl:ty)? , $($rest:tt)*) => {
#[doc = concat!("Get `", stringify!($name), "`.")]
#[must_use]
pub fn $name(&self) -> std::sync::Arc<$ty> {
std::sync::Arc::clone(&self.$field)
}

$crate::arc_getters! { $($rest)* }
};

($name:ident : $ty:ty => $field:ident $(= $impl:ty)? $(,)?) => {
#[doc = concat!("Get `", stringify!($name), "`.")]
#[must_use]
pub fn $name(&self) -> std::sync::Arc<$ty> {
std::sync::Arc::clone(&self.$field)
}
};

($name:ident : $ty:ty $(= $impl:ty)? , $($rest:tt)*) => {
#[doc = concat!("Get `", stringify!($name), "`.")]
#[must_use]
pub fn $name(&self) -> std::sync::Arc<$ty> {
std::sync::Arc::clone(&self.$name)
}

$crate::arc_getters! { $($rest)* }
};

($name:ident : $ty:ty $(= $impl:ty)? $(,)?) => {
#[doc = concat!("Get `", stringify!($name), "`.")]
#[must_use]
pub fn $name(&self) -> std::sync::Arc<$ty> {
std::sync::Arc::clone(&self.$name)
}
};
}
2 changes: 2 additions & 0 deletions crates/mcb-domain/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ mod ports;
mod schema;
#[macro_use]
mod registry;
#[macro_use]
mod di;
Loading