Skip to main content

BaseScanner

Trait BaseScanner 

Source
pub trait BaseScanner<App: Send + Sync = ()> {
    // Required methods
    fn scan<'life0, 'life1, 'async_trait>(
        &'life0 self,
        app: &'life1 App,
    ) -> Pin<Box<dyn Future<Output = Vec<ScannedModule>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn source_name(&self) -> &str;
}
Expand description

Abstract interface for framework scanners.

Implementors provide scan() for framework-specific endpoint scanning and source_name() for identification. The App type parameter allows each framework adapter to accept its own application type.

§Language-specific API shape

The Rust BaseScanner trait intentionally contains only the primitive scan() and source_name() operations, keeping it object-safe (usable as Box<dyn BaseScanner>).

Helper utilities — filter_modules, deduplicate_ids, infer_annotations_from_method — are free functions in the scanner module rather than trait default methods. This differs from Python and TypeScript where these are instance methods on the class.

Usage:

let filtered = scanner::filter_modules(&modules, Some("my.*"), None)?;
let deduplicated = scanner::deduplicate_ids(filtered);

§Note: ConventionScanner

ConventionScanner (available in Python as apcore_toolkit.ConventionScanner) is Python-only. It relies on Python’s importlib module introspection for plain-function discovery, which has no equivalent in Rust. Rust consumers should use BaseScanner implementations that work with Rust’s type system directly.

// Example: Axum adapter
struct AxumScanner;

#[async_trait]
impl BaseScanner<axum::Router> for AxumScanner {
    async fn scan(&self, app: &axum::Router) -> Vec<ScannedModule> { /* ... */ }
    fn source_name(&self) -> &str { "axum" }
}

// Example: Actix adapter
struct ActixScanner;

#[async_trait]
impl BaseScanner<()> for ActixScanner {
    async fn scan(&self, _app: &()) -> Vec<ScannedModule> { /* ... */ }
    fn source_name(&self) -> &str { "actix-web" }
}

Required Methods§

Source

fn scan<'life0, 'life1, 'async_trait>( &'life0 self, app: &'life1 App, ) -> Pin<Box<dyn Future<Output = Vec<ScannedModule>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Scan endpoints and return module definitions.

The app parameter receives framework-specific state (e.g., axum::Router, actix_web::App). Use () if no app context is needed.

Source

fn source_name(&self) -> &str

Return human-readable scanner name (e.g., “axum”, “actix-web”).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§