specta-swift 0.0.3

Export your Rust types to Swift
Documentation
# Specta Swift

[![Crates.io](https://img.shields.io/crates/v/specta-swift.svg)](https://crates.io/crates/specta-swift)
[![Documentation](https://docs.rs/specta-swift/badge.svg)](https://docs.rs/specta-swift)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Rust crate for exporting Rust types to Swift, built on top of [Specta](https://github.com/specta-rs/specta). Generate idiomatic Swift code from your Rust type definitions with support for complex unions, generics, and nested structures.

## Features

- ๐Ÿš€ **Zero Runtime Cost** - Compile-time type generation
- ๐ŸŽฏ **Idiomatic Swift** - Generates clean, Swift-idiomatic code
- ๐Ÿ”„ **Complex Unions** - Full support for Rust enums with all variant types
- ๐Ÿงฌ **Generics** - Single and multiple generic type parameters
- ๐Ÿ”— **Recursive Types** - Self-referencing and circular type definitions
- โš™๏ธ **Highly Configurable** - Naming conventions, indentation styles, optional syntax
- ๐Ÿ“ฆ **Type Safety** - Leverages Specta's robust type introspection
- ๐Ÿงช **Well Tested** - Comprehensive test suite with snapshot testing
- ๐Ÿ•’ **Special Types** - Built-in support for Duration with helper structs
- ๐Ÿ“ **Documentation** - Preserves and formats Rust doc comments in Swift
- ๐Ÿ”ง **Custom Codable** - Automatic generation of custom Codable implementations
- ๐ŸŽจ **Protocol Conformance** - Support for additional Swift protocols
- ๐Ÿ“ **File Export** - Direct export to Swift files with custom headers

## Quick Start

Add `specta-swift` and `specta-serde` to your `Cargo.toml`:

```toml
[dependencies]
specta = { version = "2.0", features = ["derive"] }
specta-serde = "0.0.12"
specta-swift = "0.1"
```

Define your Rust types:

```rust
use specta::{Type, Types};
use specta_swift::Swift;

#[derive(Type)]
struct User {
    id: u32,
    name: String,
    email: Option<String>,
    role: UserRole,
}

#[derive(Type)]
enum UserRole {
    Guest,
    User { permissions: Vec<String> },
    Admin { level: u8, department: String },
}

#[derive(Type)]
enum ApiResult<T> {
    Success { data: T, status: u16 },
    Error { message: String, code: u32 },
    Loading { progress: f32 },
}
```

Generate Swift code:

```rust
fn main() {
    let types = Types::default()
        .register::<User>()
        .register::<UserRole>()
        .register::<ApiResult<String>>();

    let swift = Swift::default();
    swift
        .export_to("./Types.swift", &types, specta_serde::format)
        .unwrap();
}
```

This generates:

```swift
// This file has been generated by Specta. DO NOT EDIT.
import Foundation

enum ApiResult<T>: Codable {
    case success(data: T, status: UInt16)
    case error(message: String, code: UInt32)
    case loading(progress: Float)
}

struct User: Codable {
    let id: UInt32
    let name: String
    let email: String?
    let role: UserRole
}

enum UserRole: Codable {
    case guest
    case user(permissions: [String])
    case admin(level: UInt8, department: String)
}
```

## Advanced Features

### Complex Union Types

Specta Swift supports all Rust enum variant types:

```rust
#[derive(Type)]
enum ComplexUnion {
    // Unit variant
    None,

    // Tuple variant
    Tuple(String, u32, bool),

    // Named fields variant
    NamedFields {
        id: u32,
        name: String,
        active: bool,
    },

    // Nested struct variant
    UserStruct(User),

    // Nested enum variant
    UserType(UserType),

    // Complex nested structure
    Complex {
        user: User,
        metadata: Vec<String>,
        settings: Option<Admin>,
    },
}
```

Generates:

```swift
enum ComplexUnion: Codable {
    case none
    case tuple(String, UInt32, Bool)
    case namedfields(id: UInt32, name: String, active: Bool)
    case userstruct(User)
    case usertype(UserType)
    case complex(user: User, metadata: [String], settings: Admin?)
}
```

### Generic Types

Full support for generic types with multiple parameters:

```rust
#[derive(Type)]
enum DatabaseResult<T, E> {
    Ok { data: T, affected_rows: u64 },
    Err { error: E, query: String },
    ConnectionError { host: String, port: u16 },
}
```

### Recursive Types

Self-referencing types are fully supported:

```rust
#[derive(Type)]
enum Shape {
    None,
    Point(f64, f64),
    Circle { center: Point, radius: f64 },
    Complex { shapes: Vec<Shape>, metadata: Option<String> },
}
```

## Configuration

### Naming Conventions

```rust
use specta_swift::{Swift, NamingConvention};

// PascalCase (default)
let swift = Swift::default();

// camelCase
let swift = Swift::new().naming(NamingConvention::CamelCase);

// snake_case
let swift = Swift::new().naming(NamingConvention::SnakeCase);
```

### Optional Styles

```rust
use specta_swift::{Swift, OptionalStyle};

// T? syntax (default)
let swift = Swift::default();

// Optional<T> syntax
let swift = Swift::new().optionals(OptionalStyle::Optional);
```

### Indentation Styles

```rust
use specta_swift::{Swift, IndentStyle};

// 4 spaces (default)
let swift = Swift::default();

// 2 spaces
let swift = Swift::new().indent(IndentStyle::Spaces(2));

// Tabs
let swift = Swift::new().indent(IndentStyle::Tabs);
```

### Custom Headers

```rust
let swift = Swift::new()
    .header("// Generated by MyApp v2.0\n// Custom header with app info\n// DO NOT EDIT MANUALLY")
    .naming(NamingConvention::SnakeCase);
```

### Additional Protocols

```rust
let swift = Swift::new()
    .add_protocol("Equatable")
    .add_protocol("Hashable")
    .add_protocol("CustomStringConvertible");
```

### Serde Integration

```rust
let swift = Swift::new()
    .add_protocol("CustomDebugStringConvertible");

let output = swift.export(&types, specta_serde::format).unwrap();
```

## Type Mapping

| Rust Type                 | Swift Type                            | Notes                          |
| ------------------------- | ------------------------------------- | ------------------------------ |
| `i8`, `i16`, `i32`, `i64` | `Int8`, `Int16`, `Int32`, `Int64`     | Signed integers                |
| `u8`, `u16`, `u32`, `u64` | `UInt8`, `UInt16`, `UInt32`, `UInt64` | Unsigned integers              |
| `f32`, `f64`              | `Float`, `Double`                     | Floating point numbers         |
| `bool`                    | `Bool`                                | Boolean values                 |
| `char`                    | `Character`                           | Single Unicode character       |
| `String`                  | `String`                              | UTF-8 strings                  |
| `Option<T>`               | `T?` or `Optional<T>`                 | Optional values (configurable) |
| `Vec<T>`                  | `[T]`                                 | Arrays                         |
| `Vec<Vec<T>>`             | `[[T]]`                               | Nested arrays                  |
| `HashMap<K, V>`           | `[K: V]`                              | Dictionaries                   |
| `(T, U)`                  | `(T, U)`                              | Tuples                         |
| `std::time::Duration`     | `RustDuration` + helper               | With automatic helper struct   |
| `struct`                  | `struct`                              | Structures                     |
| `enum`                    | `enum`                                | Enums with custom Codable      |

## Special Features

### Duration Support

`std::time::Duration` types are automatically converted to a `RustDuration` helper struct:

```rust
#[derive(Type)]
struct Metrics {
    processing_time: Duration,
    timeout: Duration,
}
```

Generates:

```swift
// MARK: - Duration Helper
public struct RustDuration: Codable {
    public let secs: UInt64
    public let nanos: UInt32

    public var timeInterval: TimeInterval {
        return Double(secs) + Double(nanos) / 1_000_000_000.0
    }
}

public struct Metrics: Codable {
    public let processingTime: RustDuration
    public let timeout: RustDuration
}
```

### Documentation Support

Rust doc comments are preserved and formatted for Swift:

```rust
/// A comprehensive user account
///
/// This struct represents a complete user account with all necessary
/// information for authentication and personalization.
///
/// # Security Notes
/// - The password field should never be logged
/// - All timestamps are in UTC
#[derive(Type)]
struct User {
    /// Unique identifier
    id: u32,
    /// User's display name
    name: String,
}
```

Generates:

```swift
/// A comprehensive user account
///
/// This struct represents a complete user account with all necessary
/// information for authentication and personalization.
///
/// # Security Notes
/// - The password field should never be logged
/// - All timestamps are in UTC
public struct User: Codable {
    /// Unique identifier
    public let id: UInt32
    /// User's display name
    public let name: String
}
```

## Examples

Check out the `examples/` directory for comprehensive examples:

- `basic_types.rs` - Basic primitive types and their Swift equivalents
- `advanced_unions.rs` - Complex enum scenarios and custom Codable implementations
- `configuration_options.rs` - All Swift exporter configuration settings
- `special_types.rs` - Duration types and special type handling
- `string_enums.rs` - String enums and custom Codable patterns
- `comprehensive_demo.rs` - Complete feature showcase (28 types!)
- `simple_usage.rs` - Quick start example
- `comments_example.rs` - Documentation and comment support

Run any example:

```bash
cargo run --example basic_types
cargo run --example comprehensive_demo
```

Generated Swift files are saved to `examples/generated/` for inspection.

## Testing

Run the test suite:

```bash
cargo test
```

The test suite includes:

- Basic type generation tests
- Comprehensive union type tests
- Advanced recursive type tests
- Duration type mapping tests
- Custom Codable implementation tests
- Configuration option tests
- Snapshot testing for generated code
- String enum handling tests
- Generic type parameter tests

## Contributing

Contributions are welcome! Please see the main [Specta repository](https://github.com/specta-rs/specta) for contribution guidelines.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Related Projects

- [Specta]https://github.com/specta-rs/specta - Core type introspection library
- [Specta TypeScript]https://github.com/specta-rs/specta/tree/main/specta-typescript - TypeScript exporter
- [Specta Go]https://github.com/specta-rs/specta/tree/main/specta-go - Go exporter