### Running Specta Swift Examples Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Instructions on how to run the provided examples using Cargo. Examples can be executed by specifying their name after `cargo run --example`. ```bash cd specta-swift cargo run --example ``` ```bash cargo run --example basic_types cargo run --example comprehensive_demo ``` -------------------------------- ### Simple Usage Example in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md A simple, focused example for getting started quickly, demonstrating basic struct and enum definitions with default and custom configurations. Run with `cargo run --example simple_usage`. ```rust use specta::{ts, Type}; #[derive(Type, Debug)] struct SimpleData { value: i32, } #[derive(Type, Debug)] enum SimpleChoice { Choice1, Choice2, } fn main() { let default_export = ts::export::().unwrap(); println!("Default Export:\n{}", default_export); let mut config = ts::Config::default(); config.type_attributes = "@custom"; let custom_export = ts::export_with_config::(config).unwrap(); println!("Custom Export:\n{}", custom_export); } ``` -------------------------------- ### Run Specta Examples Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Command-line instructions to run Specta examples using Cargo. Generated Swift files are saved in the `examples/generated/` directory. ```bash cargo run --example basic_types cargo run --example comprehensive_demo ``` -------------------------------- ### Documentation and Comments Example in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Demonstrates comprehensive documentation support, including multi-line type documentation, field-level documentation, and Swift-compatible doc comments. Run with `cargo run --example comments_example`. ```rust use specta::{ts, Type}; /// Represents a user in the system. /// /// This struct holds essential information about a user, including their unique identifier, /// username, and access permissions. #[derive(Type, Debug)] struct UserWithDocs { /// The unique identifier for the user. id: u64, /// The user's chosen username. username: String, /// A list of permissions granted to the user. permissions: Vec, } fn main() { println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### Generated Swift Code Example Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md This is an example of the Swift code generated by Specta Swift from the provided Rust types. Note the idiomatic Swift syntax and Codable conformance. ```swift // This file has been generated by Specta. DO NOT EDIT. import Foundation enum ApiResult: 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) } ``` -------------------------------- ### Comprehensive Demo in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md The ultimate example demonstrating EVERY feature in a realistic application, including complex nested relationships and various data structures. Run with `cargo run --example comprehensive_demo`. ```rust use specta::{ts, Type}; #[derive(Type, Debug)] struct UserProfile { user_id: u64, username: String, permissions: Vec, } #[derive(Type, Debug)] enum TaskStatus { ToDo, InProgress, Done, } #[derive(Type, Debug)] struct Task { id: u64, title: String, status: TaskStatus, assignee: Option, } fn main() { println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### Configuration Options in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Demonstrates all Swift exporter configuration options, including custom headers, naming conventions, indentation, and generic type styles. Run with `cargo run --example configuration_options`. ```rust use specta::{ts, Type, Def, NamedType}; #[derive(Type, Debug)] struct MyStruct { field1: i32, field2: String, } fn main() { let mut config = ts::Config::default(); config.export_to_multiple_files = true; config.type_attributes = "@objc @dynamic"; config.documentation = true; config.named_types = vec![NamedType::new::()]; let result = ts::export_with_config::(config).unwrap(); println!("{}", result); } ``` -------------------------------- ### Integrate Serde with Swift Export Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Combine Specta's Swift export with Serde for custom data formatting. This example adds `CustomDebugStringConvertible` and uses `specta_serde::format`. ```rust let swift = Swift::new() .add_protocol("CustomDebugStringConvertible"); let output = swift.export(&types, specta_serde::format).unwrap(); ``` -------------------------------- ### Basic Type Mappings in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Demonstrates fundamental Rust to Swift type conversions for primitive types, optionals, collections, tuples, simple enums, and generic structs. Run with `cargo run --example basic_types`. ```rust use specta::{ts, Type, event::Event}; use std::collections::HashMap; #[derive(Type, Debug)] struct User { id: u32, name: String, is_active: bool, tags: Vec, settings: HashMap, } #[derive(Type, Debug)] enum Status { Pending, Processing, Completed, Failed(String), } #[derive(Type, Debug)] struct Post { title: String, content: String, author: User, status: Status, } fn main() { println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### Special Type Handling in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Demonstrates special type conversions like Duration to RustDuration helper and automatic helper struct generation. Run with `cargo run --example special_types`. ```rust use specta::{ts, Type}; use std::time::Duration; #[derive(Type, Debug)] struct PerformanceMetrics { duration: Duration, name: String, } fn main() { println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### Advanced Union Scenarios in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Showcases advanced enum patterns including generic enums, recursive types, and custom Codable implementations. Run with `cargo run --example advanced_unions`. ```rust use specta::{ts, Type}; #[derive(Type, Debug)] struct TreeNode { value: T, children: Vec>, } #[derive(Type, Debug)] enum ComplexEnum { Simple(String), Nested(i32, bool), WithStruct { name: String, age: u8 }, Recursive(TreeNode), } fn main() { println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### String Enums and Custom Codable in Rust Source: https://github.com/specta-rs/specta/blob/main/specta-swift/examples/README.md Focuses on string enums, mixed enums, custom Codable implementations, and struct generation for named field variants. Run with `cargo run --example string_enums`. ```rust use specta::{ts, Type}; #[derive(Type, Debug)] enum StringEnum { OptionA, OptionB, OptionC, } #[derive(Type, Debug)] enum MixedEnum { Simple(String), Complex { value: i32, flag: bool }, } fn main() { println!("{}", ts::export::().unwrap()); println!("{}", ts::export::().unwrap()); } ``` -------------------------------- ### Export All Derived Types to a Single File Source: https://github.com/specta-rs/specta/blob/main/README.md This example demonstrates exporting all types that have the `specta::Type` trait derived, using the `specta::export()` function. It utilizes the `collect = false` attribute to prevent specific types from being automatically collected. ```rust //! NOTE: This example requires the `export` feature on the `specta` crate use specta::Type; use specta_typescript::Typescript; #[derive(Type)] pub enum MyEither { Left(L), Right(R), } #[derive(Type)] pub struct GenericType { pub my_field: String, pub generic: A, } #[derive(Type)] pub enum MyEnum { A, B, C, } #[derive(Type)] #[specta(collect = false)] pub struct DontExportMe { field: String, } fn main() { Typescript::default() .export_to("./bindings.ts", &specta::export()) .unwrap(); } ``` -------------------------------- ### Managing `Types` Registry for Export Source: https://context7.com/specta-rs/specta/llms.txt Use the `Types` registry to accumulate `NamedDataType` instances. Register types using `register::()` and merge registries with `extend()`. This example demonstrates chained registration and exporting to a file. ```rust use specta::{Type, Types}; use specta_typescript::Typescript; #[derive(Type)] pub struct Category { pub id: u32, pub label: String } #[derive(Type)] pub struct Product { pub id: u32, pub name: String, pub category: Category } #[derive(Type)] pub struct Cart { pub items: Vec, pub total: f64 } fn main() { // Chained registration — Category is transitively registered via Product let types = Types::default() .register::() .register::(); println!("Registered {} types", types.len()); // 3 // Sorted iteration guarantees stable output order across runs for ndt in types.into_sorted_iter() { println!("{} ({})", ndt.name, ndt.module_path); } // Merging two registries let extra = Types::default().register::(); let mut combined = Types::default().register::(); combined.extend(&extra); // already-known entries are kept; new ones are added Typescript::default() .export_to("./bindings.ts", &combined, specta_serde::Format) .unwrap(); } ``` -------------------------------- ### Inspect and Mutate Runtime Type Graph with DataType Source: https://context7.com/specta-rs/specta/llms.txt Operate on Specta's `DataType` enum at runtime to inspect or modify type information. This example shows inspecting a `Point` struct's `DataType` and mutating metadata on registered named types. ```rust use specta::{Type, Types}; use specta::datatype::{DataType, Primitive, NamedDataType}; #[derive(Type)] struct Point { x: f64, y: f64 } fn main() { let mut types = Types::default().register::(); // Inspect the resolved DataType let dt = ::definition(&mut types); match &dt { DataType::Reference(r) => println!("Named reference: registered as named type"), DataType::Struct(s) => println!("Inline struct with {} fields", s.fields().len()), other => println!("Other: {:?}", other), } // Iterate and mutate metadata on all registered named types types.iter_mut(|ndt: &mut NamedDataType| { if ndt.name == "Point" { ndt.docs = "A 2-D coordinate".into(); } }); // Map transforms every NamedDataType, returning a new Types let renamed = types.map(|mut ndt| { ndt.name = format!("Api_{{}}", ndt.name).into(); ndt }); for ndt in renamed.into_sorted_iter() { println!("{}", ndt.name); // Api_Point } } ``` -------------------------------- ### Deriving `Type` for Structs and Enums Source: https://context7.com/specta-rs/specta/llms.txt Attach `#[derive(Type)]` to Rust structs and enums to generate runtime type descriptions. Referenced types are automatically registered. This example shows usage with `serde` and exporting to TypeScript. ```rust use serde::{Deserialize, Serialize}; use specta::{Type, Types}; use specta_typescript::Typescript; #[derive(Serialize, Deserialize, Type)] pub struct User { pub id: u32, pub name: String, #[serde(rename = "emailAddress")] pub email_address: String, pub avatar_url: Option, // becomes `string | null` in TypeScript } #[derive(Serialize, Deserialize, Type)] pub struct Post { pub id: u32, pub title: String, pub author: User, // referenced type is auto-registered pub tags: Vec, pub status: PostStatus, } #[derive(Serialize, Deserialize, Type)] #[serde(rename_all = "camelCase")] pub enum PostStatus { Draft, InReview, Published, } fn main() { let types = Types::default() .register::(); // User and PostStatus are pulled in automatically let output = Typescript::default() .export(&types, specta_serde::Format) .expect("export failed"); // output contains: // export type User = { id: number; emailAddress: string; avatar_url: string | null; ... }; // export type PostStatus = "draft" | "inReview" | "published"; // export type Post = { id: number; title: string; author: User; tags: string[]; status: PostStatus }; println!("{output}"); } ``` -------------------------------- ### Export Rust Types to Swift Codable Structs and Enums Source: https://context7.com/specta-rs/specta/llms.txt Use `specta-swift::Swift` to generate idiomatic Swift `Codable` types from Rust types. Configure naming conventions, optional syntax, and indentation. This example shows exporting a `User` struct and `Role` enum. ```rust use specta::{Type, Types}; use specta_swift::{Swift, NamingConvention, IndentStyle, OptionalStyle}; /// A platform user #[derive(Type)] pub struct User { /// Unique identifier pub id: u32, pub name: String, pub avatar: Option, pub role: Role, } #[derive(Type)] pub enum Role { Guest, Member { permissions: Vec }, Admin { level: u8 }, } fn main() { let types = Types::default().register::(); let swift = Swift::new() .naming(NamingConvention::PascalCase) // default .indent(IndentStyle::Spaces(4)) // default .optionals(OptionalStyle::QuestionMark) // T? syntax (default) .add_protocol("Equatable") .add_protocol("Hashable"); // Export to string let output = swift.export(&types, specta_serde::format).unwrap(); // output contains: // struct User: Codable, Equatable, Hashable { ... } // enum Role: Codable, Equatable, Hashable { case guest; case member(...); case admin(...) } // Export directly to file Swift::default() .export_to("./Types.swift", &types, specta_serde::format) .unwrap(); } ``` -------------------------------- ### Add Specta Swift Dependencies Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Include specta-swift and specta-serde in your Cargo.toml to enable type export functionality. ```toml [dependencies] specta = { version = "2.0", features = ["derive"] } specta-serde = "0.0.11" specta-swift = "0.1" ``` -------------------------------- ### Run Specta Tests Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Execute the test suite for Specta-Swift using Cargo. This command verifies the functionality of type generation, union types, recursive types, and custom Codable implementations. ```bash cargo test ``` -------------------------------- ### Rust Documentation Comments to Swift Doc Comments Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Shows how Rust documentation comments (///) are preserved and formatted for Swift, including fields and sections like `# Security Notes`. ```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, } ``` ```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 } ``` -------------------------------- ### Configure Swift Naming Conventions Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Customize the naming convention for generated Swift code. Options include PascalCase (default), camelCase, and snake_case. ```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); ``` -------------------------------- ### Configure Swift Optional Styles Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Choose the syntax for representing optional types in Swift. The default is `T?`, but `Optional` can also be used. ```rust use specta_swift::{Swift, OptionalStyle}; // T? syntax (default) let swift = Swift::default(); // Optional syntax let swift = Swift::new().optionals(OptionalStyle::Optional); ``` -------------------------------- ### Using Attributes for Runtime Metadata Source: https://context7.com/specta-rs/specta/llms.txt Demonstrates how to use `Attributes` to store and manage type-erased metadata on datatype nodes. This is useful for format companions to record representation choices. ```rust use specta::datatype::Attributes; let mut attrs = Attributes::default(); // Insert typed values attrs.insert("serde_tag", "type".to_string()); attrs.insert("serde_content", "data".to_string()); attrs.insert("version", 2u32); assert!(attrs.contains_key("serde_tag")); assert_eq!(attrs.get_named_as::("serde_tag"), Some(&"type".to_string())); assert_eq!(attrs.get_named_as::("version"), Some(&2u32)); // Merge attributes let mut extra = Attributes::default(); extra.insert("deprecated", true); attrs.extend(extra); assert_eq!(attrs.len(), 4); attrs.remove("version"); assert_eq!(attrs.len(), 3); ``` -------------------------------- ### Export Rust Types to Multiple Languages (TypeScript & Swift) Source: https://github.com/specta-rs/specta/blob/main/README.md Shows how to export the same Rust types to both TypeScript and Swift formats using Specta. This is useful for maintaining consistency across different platforms. ```rust use specta::{Type, Types}; use specta_typescript::Typescript; use specta_swift::Swift; #[derive(Type)] pub struct User { pub id: u32, pub name: String, pub email: Option, } fn main() { let types = Types::default() .register::(); // Export to TypeScript (stable) Typescript::default() .export_to("./types.ts", &types) .unwrap(); // Export to Swift (stable) Swift::default() .export_to("./Types.swift", &types) .unwrap(); // Note: Other exporters are in development } ``` -------------------------------- ### Add Specta and Exporter Crates Source: https://github.com/specta-rs/specta/blob/main/README.md Use `cargo add` to include the core Specta library and any desired language exporter crates in your Rust project. ```bash cargo add specta cargo add specta_typescript # TypeScript (stable) cargo add specta_swift # Swift (stable) cargo add specta_rust # Rust (partial - basic types) cargo add specta_openapi # OpenAPI/Swagger (partial - primitives) # cargo add specta_go # Go (planned) # cargo add specta_kotlin # Kotlin (planned) ``` -------------------------------- ### Configure Indentation Styles for Swift Export Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Customize the indentation style for generated Swift code. Supports 4 spaces (default), 2 spaces, or tabs. ```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); ``` -------------------------------- ### Collecting Multiple Function Signatures with `collect_functions!` Source: https://context7.com/specta-rs/specta/llms.txt The `collect_functions!` macro gathers multiple `#[specta]`-annotated functions into a `Vec` and populates a `Types` registry with all referenced named types in a single call. ```rust use specta::{Type, Types, function::collect_functions}; #[specta::specta] fn add(a: i32, b: i32) -> i32 { a + b } #[specta::specta] fn greet(name: String) -> String { format!("Hello, {name}!") } #[specta::specta] async fn save_record(record: Record) -> bool { true } #[derive(Type)] pub struct Record { pub key: String, pub value: String } fn main() { let mut types = Types::default(); let fns = collect_functions![add, greet, save_record](&mut types); for f in &fns { println!( "{}{} ({} args)", if f.asyncness() { "async " } else { "" }, f.name(), f.args().len() ); } // async add (2 args) // greet (1 args) // async save_record (1 args) println!("{} named types registered", types.len()); // 1 (Record) } ``` -------------------------------- ### Generate Swift Code from Rust Types Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Use the `Swift` exporter to generate a Swift file containing the type definitions from your registered Rust types. ```rust fn main() { let types = Types::default() .register::() .register::() .register::>(); let swift = Swift::default(); swift .export_to("./Types.swift", &types, specta_serde::format) .unwrap(); } ``` -------------------------------- ### Export Rust Types to TypeScript Source: https://github.com/specta-rs/specta/blob/main/README.md Demonstrates how to derive `specta::Type` for Rust structs and enums, then export them to a TypeScript file using `specta_typescript::Typescript`. Ensure all referenced types are registered or implicitly included. ```rust use specta::{Type, Types}; use specta_typescript::Typescript; #[derive(Type)] pub struct TypeOne { pub a: String, pub b: GenericType, #[serde(rename = "cccccc")] pub c: MyEnum, } #[derive(Type)] pub struct GenericType { pub my_field: String, pub generic: A, } #[derive(Type)] pub enum MyEnum { A, B, C, } fn main() { let types = Types::default() // You don't need to specify `GenericType` or `MyEnum` because they are referenced by `TypeOne` .register::(); Typescript::default() .export_to("./bindings.ts", &types) .unwrap(); // if you need more control over file saving assert_eq!( Typescript::default().export(&types).unwrap(), r###"// This file has been generated by Specta. DO NOT EDIT. export type GenericType = { my_field: string; generic: A }; export type MyEnum = "A" | "B" | "C"; export type TypeOne = { a: string; b: GenericType; cccccc: MyEnum }; "### ); } ``` -------------------------------- ### Add Custom Headers to Swift Export Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Include custom header comments in the generated Swift files. Useful for adding version information or build metadata. ```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); ``` -------------------------------- ### Apply Serde Wire-Format Rules with specta-serde Source: https://context7.com/specta-rs/specta/llms.txt Use `specta-serde` to translate Serde attributes into Specta's `Attributes` layer, ensuring exported types match the actual JSON shape. Supports unified (symmetric) and split (asymmetric) formats. ```rust use serde::{Deserialize, Serialize}; use specta::{Type, Types}; use specta_typescript::Typescript; // Unified: symmetric rename_all #[derive(Serialize, Deserialize, Type)] #[serde(rename_all = "camelCase")] struct ApiUser { user_id: u32, display_name: String } // Phased: asymmetric serde_as transformation #[derive(Type, Serialize, Deserialize)] #[serde(untagged)] enum OneOrManyString { One(String), Many(Vec) } #[serde_with::serde_as] #[derive(Type, Serialize, Deserialize)] struct Filters { #[serde_with::serde_as(as = "serde_with::OneOrMany<_>")] #[specta(type = specta_serde::Phased, OneOrManyString>)] tags: Vec, } fn main() { // Unified format let types = Types::default().register::(); let unified = Typescript::default() .export(&types, specta_serde::Format).unwrap(); assert!(unified.contains("userId: number")); assert!(unified.contains("displayName: string")); // Split phases let types2 = Types::default().register::(); let phased = Typescript::default() .export(&types2, specta_serde::FormatPhases).unwrap(); assert!(phased.contains("Filters_Serialize")); assert!(phased.contains("Filters_Deserialize")); } ``` -------------------------------- ### TypeScript Exporter for Generating `.ts` Type Definitions Source: https://context7.com/specta-rs/specta/llms.txt Use `specta-typescript::Typescript` to convert a `Types` registry into a TypeScript source string or write it to a file. It supports generics, unions, optional types, and serde attributes. ```rust use specta::{Type, Types}; use specta_typescript::Typescript; #[derive(Type)] pub struct GenericResponse { pub data: T, pub ok: bool, } #[derive(Type)] pub enum MyEnum { A, B, C } #[derive(Type)] pub struct MyStruct { pub a: String, pub b: GenericResponse, #[serde(rename = "cValue")] pub c: MyEnum, } fn main() { let types = Types::default().register::(); // Export to string let ts = Typescript::default() .export(&types, specta_serde::Format) .unwrap(); assert!(ts.contains("export type MyEnum = \"A\" | \"B\" | \"C\"")); assert!(ts.contains("export type GenericResponse")); assert!(ts.contains("cValue: MyEnum")); // Export directly to file Typescript::default() .export_to("./bindings.ts", &types, specta_serde::Format) .unwrap(); } ``` -------------------------------- ### Capturing Function Signatures with `#[specta]` and `fn_datatype!` Source: https://context7.com/specta-rs/specta/llms.txt Use the `#[specta]` attribute to record function metadata (name, args, return type, docs, async flag). The `fn_datatype!` macro retrieves this metadata at runtime and registers types. This enables framework crates to generate typed IPC bindings. ```rust use specta::{*, datatype::*, function::fn_datatype}; #[specta] fn create_user(name: String, age: u32) -> User { todo!() } #[specta] async fn fetch_posts(page: u32) -> Vec { todo!() } #[derive(Type)] pub struct User { pub id: u32, pub name: String } #[derive(Type)] pub struct Post { pub id: u32, pub title: String } fn main() { let mut types = Types::default(); let create = fn_datatype!(create_user)(&mut types); assert_eq!(create.name(), "create_user"); assert_eq!(create.args().len(), 2); assert!(!create.asyncness()); let fetch = fn_datatype!(fetch_posts)(&mut types); assert_eq!(fetch.name(), "fetch_posts"); assert!(fetch.asyncness()); // types now contains User and Post println!("Collected {} named types", types.len()); // 2 } ``` -------------------------------- ### Generate TypeScript Types with Split Serde Phases Source: https://github.com/specta-rs/specta/blob/main/specta-serde/README.md Use `specta_serde::format_phases` when the wire format differs between serialization and deserialization. This can produce distinct `_Serialize` and `_Deserialize` TypeScript types, along with a union type `TypeName` for general use. This is common with directional Serde metadata or explicit `#[specta(type = ...)]` overrides. ```rust use serde::{Deserialize, Serialize}; use serde_with::{OneOrMany, serde_as}; use specta::{Type, Types}; use specta_typescript::Typescript; #[derive(Type, Serialize, Deserialize)] #[serde(untagged)] enum OneOrManyString { One(String), Many(Vec), } #[serde_as] #[derive(Type, Serialize, Deserialize)] struct Filters { #[serde_as(as = "OneOrMany<_>")] #[specta(type = specta_serde::Phased, OneOrManyString>)] tags: Vec, } let types = Types::default().register::(); let output = Typescript::default() .export(&types, specta_serde::format_phases) .unwrap(); assert!(output.contains("Filters_Serialize")); assert!(output.contains("Filters_Deserialize")); assert!(output.contains("OneOrManyString")); ``` -------------------------------- ### Generate TypeScript Types with Unified Serde Format Source: https://github.com/specta-rs/specta/blob/main/specta-serde/README.md Use `specta_serde::format` when Serde behavior is symmetric. This format produces a single TypeScript type. It may error with certain Serde attributes like `#[serde(rename(serialize = "a", deserialize = "b"))]` as the correct type is ambiguous. ```rust use specta::Types; use specta_typescript::Typescript; #[derive(specta::Type, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] struct User { user_id: u32, } let types = Types::default().register::(); let output = Typescript::default() .export(&types, specta_serde::format) .unwrap(); assert!(output.contains("export type User")); assert!(output.contains("userId: number")); ``` -------------------------------- ### Add Additional Protocols to Swift Structs/Enums Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Specify additional Swift protocols that generated types should conform to, such as Equatable or Hashable. ```rust let swift = Swift::new() .add_protocol("Equatable") .add_protocol("Hashable") .add_protocol("CustomStringConvertible"); ``` -------------------------------- ### Rust Generic Type Definition Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Illustrates a Rust enum with multiple generic type parameters, showcasing Specta Swift's support for complex generic structures. ```rust #[derive(Type)] enum DatabaseResult { Ok { data: T, affected_rows: u64 }, Err { error: E, query: String }, ConnectionError { host: String, port: u16 }, } ``` -------------------------------- ### Rust Enum Variants for Complex Unions Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Demonstrates various Rust enum variant types including unit, tuple, named fields, and nested structures, all supported by Specta Swift. ```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, settings: Option, }, } ``` -------------------------------- ### Rust Duration Type to Swift Conversion Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Demonstrates how `std::time::Duration` in Rust is automatically converted to a `RustDuration` helper struct in Swift, including a `timeInterval` property. ```rust use std::time::Duration; #[derive(Type)] struct Metrics { processing_time: Duration, timeout: Duration, } ``` ```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 } ``` -------------------------------- ### Generated Swift Code for Complex Unions Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Shows the Swift representation of Rust's complex union types, including unit, tuple, named fields, and nested variants. ```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?) } ``` -------------------------------- ### Define Rust Types for Swift Export Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Derive the `Type` trait for your Rust structs and enums to make them introspectable by Specta for Swift code generation. ```rust use specta::{Type, Types}; use specta_swift::Swift; #[derive(Type)] struct User { id: u32, name: String, email: Option, role: UserRole, } #[derive(Type)] enum UserRole { Guest, User { permissions: Vec }, Admin { level: u8, department: String }, } #[derive(Type)] enum ApiResult { Success { data: T, status: u16 }, Error { message: String, code: u32 }, Loading { progress: f32 }, } ``` -------------------------------- ### Deriving Specta Type for Structs and Collecting Types Source: https://context7.com/specta-rs/specta/llms.txt Derive the `Type` trait for Rust structs to make them introspectable by Specta. Use `specta::collect()` to gather all types that derive `Type` and are not marked with `#[specta(collect = false)]`. This is useful for generating API bindings. ```rust use specta::Type; use specta_typescript::Typescript; #[derive(Type)] pub struct User { pub id: String, pub name: String } #[derive(Type)] pub struct Post { pub id: String, pub author: User, pub comments: Vec } #[derive(Type)] pub struct Comment { pub body: String } // Derives Type but is excluded from the global store #[derive(Type)] #[specta(collect = false)] pub struct InternalMetrics { pub latency_ms: u64 } fn main() -> Result<(), Box> { // collect() returns User, Post, Comment — InternalMetrics is absent let output = Typescript::default() .export(&specta::collect(), specta_serde::Format)?; println!("{output}"); Ok(()) } ``` -------------------------------- ### Rust Recursive Type Definition Source: https://github.com/specta-rs/specta/blob/main/specta-swift/README.md Defines a Rust enum `Shape` that recursively references itself, demonstrating Specta Swift's capability to handle self-referencing types. ```rust #[derive(Type)] enum Shape { None, Point(f64, f64), Circle { center: Point, radius: f64 }, Complex { shapes: Vec, metadata: Option }, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.