infiltrait 0.1.0

A procedural macro that automatically generates trait definitions from implementation blocks
Documentation
# Infiltrait

A Rust procedural macro that automatically generates trait definitions from implementation blocks.

## Overview

The `#[infiltrait]` attribute macro allows you to define a trait and its implementation simultaneously by writing only the impl block. This eliminates the need to separately define the trait interface, reducing code duplication and keeping related code together.

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
infiltrait = "0.1.0"
```

## Quick Start

```rust
use infiltrait::infiltrait;

struct Calculator;

#[infiltrait]
impl Arithmetic for Calculator {
    fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }

    fn multiply(&self, a: i32, b: i32) -> i32 {
        a * b
    }
}

// The macro automatically generates:
// trait Arithmetic {
//     fn add(&self, a: i32, b: i32) -> i32;
//     fn multiply(&self, a: i32, b: i32) -> i32;
// }

// Now you can use the trait normally:
fn calculate<T: Arithmetic>(calc: &T) -> i32 {
    let sum = calc.add(2, 3);
    calc.multiply(sum, 4)
}
```

## Features

- **Zero Runtime Overhead**: Pure compile-time code generation
- **Full Feature Support**: Methods, associated types, and associated constants
- **Visibility Control**: Respects `pub`, `pub(crate)`, and other visibility modifiers
- **Safety Preservation**: Maintains `unsafe` markers where appropriate
- **Clear Error Messages**: Helpful compile-time diagnostics

## Examples

### Basic Methods

```rust
use infiltrait::infiltrait;

struct Logger;

#[infiltrait]
impl Logging for Logger {
    fn info(&self, message: &str) {
        println!("[INFO] {}", message);
    }

    fn error(&self, message: &str) {
        eprintln!("[ERROR] {}", message);
    }
}
```

### Associated Types and Constants

```rust
use infiltrait::infiltrait;

struct Database;

#[infiltrait]
impl Storage for Database {
    type Item = String;
    const MAX_CAPACITY: usize = 1000;

    fn store(&mut self, item: Self::Item) -> Result<(), &'static str> {
        // Implementation details...
        Ok(())
    }

    fn capacity(&self) -> usize {
        Self::MAX_CAPACITY
    }
}
```

### Public Traits

```rust
use infiltrait::infiltrait;

struct ApiService;

#[infiltrait]
pub impl PublicApi for ApiService {
    fn process_request(&self, data: &str) -> String {
        format!("Processed: {}", data)
    }
}

// The generated trait will also be public:
// pub trait PublicApi { ... }
```

### Generic Implementations

```rust
use infiltrait::infiltrait;

struct Container<T> {
    value: T,
}

#[infiltrait]
impl<T: Clone> Wrapper<T> for Container<T> {
    fn get(&self) -> T {
        self.value.clone()
    }

    fn set(&mut self, value: T) {
        self.value = value;
    }
}
```

### Unsafe Traits

```rust
use infiltrait::infiltrait;

struct RawPointer(*mut u8);

#[infiltrait]
unsafe impl UnsafeOperations for RawPointer {
    unsafe fn read(&self) -> u8 {
        *self.0
    }

    unsafe fn write(&mut self, value: u8) {
        *self.0 = value;
    }
}
```

## Use Cases

### Rapid Prototyping

When exploring API designs, `infiltrait` lets you focus on the implementation without getting bogged down in trait definitions:

```rust
use infiltrait::infiltrait;

struct GameEngine;

#[infiltrait]
impl GameLoop for GameEngine {
    fn update(&mut self, delta_time: f32) {
        // Game logic here...
    }

    fn render(&self) {
        // Rendering code here...
    }
}
```

### Library Development

Create clean APIs where the trait and implementation are defined together:

```rust
use infiltrait::infiltrait;

pub struct HttpClient;

#[infiltrait]
pub impl HttpRequests for HttpClient {
    async fn get(&self, url: &str) -> Result<String, Box<dyn std::error::Error>> {
        // HTTP GET implementation
        Ok("response".to_string())
    }

    async fn post(&self, url: &str, body: &str) -> Result<String, Box<dyn std::error::Error>> {
        // HTTP POST implementation
        Ok("response".to_string())
    }
}
```

### Testing and Mocking

Generate traits that can be easily mocked for testing:

```rust
use infiltrait::infiltrait;

struct FileSystem;

#[infiltrait]
impl FileOperations for FileSystem {
    fn read_file(&self, path: &str) -> std::io::Result<String> {
        std::fs::read_to_string(path)
    }

    fn write_file(&self, path: &str, content: &str) -> std::io::Result<()> {
        std::fs::write(path, content)
    }
}

// Easy to create a mock for testing:
struct MockFileSystem;

impl FileOperations for MockFileSystem {
    fn read_file(&self, _path: &str) -> std::io::Result<String> {
        Ok("mock content".to_string())
    }

    fn write_file(&self, _path: &str, _content: &str) -> std::io::Result<()> {
        Ok(())
    }
}
```

## Limitations

- **Trait Names**: Cannot contain lifetimes or generic parameters in the trait name itself
- **Implementation Only**: Only works with trait implementations, not inherent impls
- **Single Trait**: Each `#[infiltrait]` attribute generates exactly one trait

## Error Handling

The macro provides clear error messages for common mistakes:

```rust
use infiltrait::infiltrait;

struct MyStruct;

// ❌ Error: Please name a trait to implement
#[infiltrait]
impl MyStruct {
    fn method(&self) {}
}

// ❌ Error: Trait may not contain lifetimes or generics
#[infiltrait]
impl MyTrait<T> for MyStruct {
    fn method(&self) {}
}
```

## How It Works

The `infiltrait` macro:

1. Parses the implementation block and extracts the trait name
2. Converts each implementation item into its corresponding trait item:
   - Method implementations → Method signatures
   - Associated constants → Associated constant declarations
   - Associated types → Associated type declarations
3. Generates both the trait definition and preserves the original implementation
4. Applies the same visibility and safety modifiers to the generated trait

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.