{"id":29308812,"url":"https://github.com/tomoikey/typesafe_builder","last_synced_at":"2025-09-11T16:08:11.307Z","repository":{"id":296610520,"uuid":"993948683","full_name":"tomoikey/typesafe_builder","owner":"tomoikey","description":"🚀 The Ultimate Builder Pattern Implementation Powered by Rust's Type System. Type safety is not a luxury, it's a necessity.","archived":false,"fork":false,"pushed_at":"2025-08-16T04:01:18.000Z","size":71,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-16T05:39:18.384Z","etag":null,"topics":["builder","crate","crates","crates-io","library","patterns","rust","rust-lang","typesafe"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomoikey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-31T21:40:35.000Z","updated_at":"2025-08-16T05:03:32.000Z","dependencies_parsed_at":"2025-06-07T22:45:52.542Z","dependency_job_id":null,"html_url":"https://github.com/tomoikey/typesafe_builder","commit_stats":null,"previous_names":["tomoikey/typesafe_builder"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/tomoikey/typesafe_builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomoikey%2Ftypesafe_builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomoikey%2Ftypesafe_builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomoikey%2Ftypesafe_builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomoikey%2Ftypesafe_builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomoikey","download_url":"https://codeload.github.com/tomoikey/typesafe_builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomoikey%2Ftypesafe_builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274665304,"owners_count":25327166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builder","crate","crates","crates-io","library","patterns","rust","rust-lang","typesafe"],"created_at":"2025-07-07T07:16:13.120Z","updated_at":"2025-09-11T16:08:11.296Z","avatar_url":"https://github.com/tomoikey.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# TypeSafe Builder\n\n\u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/typesafe_builder.svg\" alt=\"crates.io\"/\u003e\n    \u003cimg src=\"https://img.shields.io/crates/d/typesafe_builder\" alt=\"downloads\"/\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/tomoikey/typesafe_builder\" alt=\"license\"/\u003e\n    \u003cimg src=\"https://img.shields.io/badge/rustc-1.87+-blue\" alt=\"rustc\"/\u003e\n\u003c/div\u003e\n\n\u003cdiv\u003e\n    \u003ca href=\"https://github.com/tomoikey/typesafe_builder/stargazers\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/stars/tomoikey/typesafe_builder?style=social\" alt=\"GitHub stars\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/tomoikey/typesafe_builder/network/members\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/forks/tomoikey/typesafe_builder?style=social\" alt=\"GitHub forks\"/\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\n\u003ch3\u003eCompile-Time Type Safety • Zero Runtime Cost • Blazing Fast Builds\u003c/h3\u003e\n\n**The Ultimate Builder Pattern Implementation Powered by Rust's Type System**\n\n\u003cimg width=\"550\" src=\"https://github.com/user-attachments/assets/a72e996f-5f18-45ed-ab61-5f56bc04e8cc\"\u003e\n\n*Eliminate bugs at the type level and revolutionize your development experience*\n\n---\n\u003c/div\u003e\n\n## Why TypeSafe Builder?\n\nTraditional builder patterns can't detect missing required fields until runtime.\n**TypeSafe Builder** leverages Rust's powerful type system to verify all constraints **at compile time**.\n\n```rust\n// ❌ Traditional builder - potential runtime errors\nlet user = UserBuilder::new()\n    .name(\"Alice\")\n    .build()?; // Compiles even with missing required fields\n\n// ✅ TypeSafe Builder - compile-time safety guarantee\nlet user = UserBuilder::new()\n    .with_name(\"Alice\".to_string())\n    .with_email(\"alice@example.com\".to_string()) // Compile error if email is required\n    .build(); // Always guaranteed to succeed\n```\n\n## Key Features\n\n### Type-Level Constraint System\n- **Required Fields** - Completely prevent missing required field configuration\n- **Optional Fields** - Freely configurable fields\n- **Default Values** - Fields with intelligent default values using `Default::default()` or custom expressions\n- **Conditional Requirements** - Express dynamic dependencies at the type level\n- **Complex Logic** - Support for AND/OR/NOT operators in complex conditional expressions\n- **Into Conversion** - Ergonomic setters with automatic type conversion via `Into\u003cT\u003e`\n\n### Performance Characteristics\n- **Zero Runtime Cost** - All validation completed at compile time\n\n### Safety Guarantees\n- **No Panic** - Complete elimination of runtime panics\n\n## Quick Start\n\n```toml\n[dependencies]\ntypesafe_builder = \"*.*.*\" # Replace with the actual version\n```\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct User {\n    #[builder(required)]\n    name: String,\n    #[builder(optional)]\n    age: Option\u003cu32\u003e,\n    #[builder(default = \"String::from(\\\"user@example.com\\\")\")]\n    email: String,\n    #[builder(default)]\n    active: bool,\n}\n\n// Type-safe builder pattern\nlet user = UserBuilder::new()\n    .with_name(\"Alice\".to_string())\n    .with_age(30)\n    .build(); // email will be \"user@example.com\", active will be false\n```\n\n## Advanced Features\n\n### 1. Conditional Required Fields\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct Account {\n    #[builder(optional)]\n    email: Option\u003cString\u003e,\n    #[builder(required_if = \"email\")]  // Required when email is set\n    email_verified: Option\u003cbool\u003e,\n}\n\n// ✅ Compiles successfully\nlet account1 = AccountBuilder::new().build();\n\n// ✅ Compiles successfully\nlet account2 = AccountBuilder::new()\n    .with_email(\"user@example.com\".to_string())\n    .with_email_verified(true)\n    .build();\n\n// ❌ Compile error: email_verified is not set\n// let account3 = AccountBuilder::new()\n//     .with_email(\"user@example.com\".to_string())\n//     .build();\n```\n\n### 2. Conditional Optional Fields\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct Config {\n    #[builder(optional)]\n    debug_mode: Option\u003cbool\u003e,\n    #[builder(optional_if = \"debug_mode\")]  // Required when debug_mode is not set\n    log_level: Option\u003cString\u003e,\n}\n\n// ✅ When debug_mode is not set, log_level is required\nlet config1 = ConfigBuilder::new()\n    .with_log_level(\"INFO\".to_string())\n    .build();\n\n// ✅ When debug_mode is set, log_level is optional\nlet config2 = ConfigBuilder::new()\n    .with_debug_mode(true)\n    .build();\n```\n\n### 3. Complex Conditional Logic\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct ApiClient {\n    #[builder(optional)]\n    use_auth: Option\u003cbool\u003e,\n    #[builder(optional)]\n    use_https: Option\u003cbool\u003e,\n    #[builder(optional)]\n    api_key: Option\u003cString\u003e,\n\n    // Secret is required if using auth OR HTTPS\n    #[builder(required_if = \"use_auth || use_https\")]\n    secret: Option\u003cString\u003e,\n\n    // Certificate is required only when using both auth AND HTTPS\n    #[builder(required_if = \"use_auth \u0026\u0026 use_https\")]\n    certificate: Option\u003cString\u003e,\n\n    // Warning is required when using neither auth NOR HTTPS\n    #[builder(required_if = \"!use_auth \u0026\u0026 !use_https\")]\n    insecure_warning: Option\u003cString\u003e,\n\n    // Complex condition: Token required when (auth OR HTTPS) AND (no API key)\n    #[builder(required_if = \"(use_auth || use_https) \u0026\u0026 !api_key\")]\n    fallback_token: Option\u003cString\u003e,\n}\n\n// ✅ All dependencies satisfied (auth + HTTPS)\nlet client1 = ApiClientBuilder::new()\n    .with_use_auth(true)\n    .with_use_https(true)\n    .with_api_key(\"key123\".to_string())\n    .with_secret(\"secret456\".to_string())\n    .with_certificate(\"cert.pem\".to_string())\n    .build();\n\n// ✅ Insecure configuration with warning\nlet client2 = ApiClientBuilder::new()\n    .with_use_auth(false)\n    .with_use_https(false)\n    .with_insecure_warning(\"WARNING: Insecure connection!\".to_string())\n    .build();\n\n// ✅ Using fallback token when API key is not set\nlet client3 = ApiClientBuilder::new()\n    .with_use_auth(true)\n    .with_secret(\"secret\".to_string())\n    .with_fallback_token(\"backup_token\".to_string())\n    .build();\n```\n\n### 4. Default Values\n\nTypeSafe Builder supports two ways to specify default values:\n\n#### Simple Default Values (using `Default::default()`)\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct Config {\n    // Uses String::default() (empty string)\n    #[builder(default)]\n    name: String,\n\n    // Uses i32::default() (0)\n    #[builder(default)]\n    port: i32,\n\n    // Uses bool::default() (false)\n    #[builder(default)]\n    enabled: bool,\n\n    // Uses Vec::default() (empty vector)\n    #[builder(default)]\n    items: Vec\u003cString\u003e,\n\n    // Uses HashMap::default() (empty map)\n    #[builder(default)]\n    metadata: std::collections::HashMap\u003cString, String\u003e,\n\n    // Works with custom types that implement Default\n    #[builder(default)]\n    custom_field: MyCustomType,\n\n    #[builder(required)]\n    service_name: String,\n}\n\n// ✅ Use default values\nlet config = ConfigBuilder::new()\n    .with_service_name(\"my-service\".to_string())\n    .build();\n// name: \"\", port: 0, enabled: false, items: [], metadata: {}, custom_field: MyCustomType::default()\n```\n\n#### Custom Default Expressions\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct ServerConfig {\n    #[builder(default = \"String::from(\\\"localhost\\\")\")]\n    host: String,\n\n    #[builder(default = \"8080\")]\n    port: u16,\n\n    #[builder(default = \"vec![\\\"GET\\\".to_string(), \\\"POST\\\".to_string()]\")]\n    allowed_methods: Vec\u003cString\u003e,\n\n    #[builder(default = \"std::collections::HashMap::new()\")]\n    headers: std::collections::HashMap\u003cString, String\u003e,\n\n    #[builder(required)]\n    service_name: String,\n\n    #[builder(optional)]\n    ssl_cert: Option\u003cString\u003e,\n}\n\n// ✅ Use default values\nlet config1 = ServerConfigBuilder::new()\n    .with_service_name(\"my-api\".to_string())\n    .build();\n// host: \"localhost\", port: 8080, allowed_methods: [\"GET\", \"POST\"], headers: {}\n\n// ✅ Override some defaults\nlet config2 = ServerConfigBuilder::new()\n    .with_service_name(\"my-api\".to_string())\n    .with_host(\"0.0.0.0\".to_string())\n    .with_port(3000)\n    .build();\n// host: \"0.0.0.0\", port: 3000, allowed_methods: [\"GET\", \"POST\"], headers: {}\n\n// ✅ Complex default expressions\n#[derive(Builder)]\nstruct AppConfig {\n    #[builder(default = \"std::env::var(\\\"APP_NAME\\\").unwrap_or_else(|_| \\\"default-app\\\".to_string())\")]\n    app_name: String,\n\n    #[builder(default = \"chrono::Utc::now()\")]\n    created_at: chrono::DateTime\u003cchrono::Utc\u003e,\n\n    #[builder(default = \"uuid::Uuid::new_v4()\")]\n    instance_id: uuid::Uuid,\n}\n```\n\n#### Mixed Default Types\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct MixedConfig {\n    // Simple default (uses Default::default())\n    #[builder(default)]\n    name: String,\n\n    // Custom expression default\n    #[builder(default = \"42\")]\n    port: i32,\n\n    // Simple default for collections\n    #[builder(default)]\n    tags: Vec\u003cString\u003e,\n\n    // Custom expression for complex initialization\n    #[builder(default = \"std::collections::HashMap::from([(\\\"key\\\".to_string(), \\\"value\\\".to_string())])\")]\n    metadata: std::collections::HashMap\u003cString, String\u003e,\n}\n\nlet config = MixedConfigBuilder::new().build();\n// name: \"\", port: 42, tags: [], metadata: {\"key\": \"value\"}\n```\n\nKey features of default values:\n- **Simple defaults**: Use `#[builder(default)]` for types implementing `Default`\n- **Custom expressions**: Use `#[builder(default = \"expression\")]` for any valid Rust expression\n- **No type restrictions**: Works with primitives, collections, function calls, etc.\n- **Environment variables**: Access environment variables at build time (custom expressions)\n- **Function calls**: Call any function or method as default value (custom expressions)\n- **Standalone attribute**: Cannot be combined with `required`, `optional`, etc.\n- **Zero runtime cost**: All defaults are computed at build time\n\n### 5. Negation Operator Support\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct Database {\n    #[builder(optional)]\n    use_ssl: Option\u003cbool\u003e,\n\n    // Warning message required when NOT using SSL\n    #[builder(required_if = \"!use_ssl\")]\n    warning_message: Option\u003cString\u003e,\n}\n\n// ✅ Warning configuration for non-SSL usage\nlet db = DatabaseBuilder::new()\n    .with_use_ssl(false)\n    .with_warning_message(\"Insecure connection!\".to_string())\n    .build();\n```\n\n### 6. Into Conversion Support\n\nThe `#[builder(into)]` attribute allows setter methods to accept any type that implements `Into\u003cT\u003e` for the field type `T`, providing more ergonomic APIs:\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\nstruct User {\n    #[builder(required)]\n    #[builder(into)]\n    name: String,\n\n    #[builder(optional)]\n    #[builder(into)]\n    email: Option\u003cString\u003e,\n}\n\n// ✅ Accept \u0026str directly (converts to String via Into)\nlet user1 = UserBuilder::new()\n    .with_name(\"Alice\")  // \u0026str -\u003e String\n    .with_email(\"alice@example.com\")  // \u0026str -\u003e String\n    .build();\n\n// ✅ Still works with String directly\nlet user2 = UserBuilder::new()\n    .with_name(\"Bob\".to_string())\n    .build();\n```\n\nKey benefits:\n- Ergonomic APIs: Accept `\u0026str` for `String` fields without manual conversion\n- Type flexibility: Any `Into\u003cT\u003e` implementation works automatically\n- Zero overhead: Conversion happens at the call site\n- Backward compatible: Works alongside existing setter patterns\n\n### 7. Custom Builder Name\n\n```rust\nuse typesafe_builder::*;\n\n#[derive(Builder)]\n#[builder(name = \"MyCustomBuilder\")]  // Customize the builder name\nstruct User {\n    #[builder(required)]\n    name: String,\n}\n\n// Use the customized builder name\nlet user = MyCustomBuilder::new()\n    .with_name(\"Alice\".to_string())\n    .build();\n```\n\n## Error Handling\n\n### Compile-Time Error Examples\n\n```rust\n#[derive(Builder)]\nstruct User {\n    #[builder(required)]\n    name: String,\n}\n\n// ❌ Compile error\nlet user = UserBuilder::new().build();\n//                           ^^^^^\n// error: no method named `build` found for struct `UserBuilder\u003c_TypesafeBuilderEmpty\u003e`\n//        method `build` is available on `UserBuilder\u003c_TypesafeBuilderFilled\u003e`\n```\n\n### Constraint Violation Error Examples\n\n```rust\n#[derive(Builder)]\nstruct Config {\n    #[builder(optional)]\n    feature: Option\u003cbool\u003e,\n    #[builder(required_if = \"feature\")]\n    config: Option\u003cString\u003e,\n}\n\n// ❌ Compile error\nlet config = ConfigBuilder::new()\n    .with_feature(true)\n    .build();\n//   ^^^^^\n// error: no method named `build` found for struct `ConfigBuilder\u003c_TypesafeBuilderFilled, _TypesafeBuilderEmpty\u003e`\n//        method `build` is available on `ConfigBuilder\u003c_TypesafeBuilderFilled, _TypesafeBuilderFilled\u003e`\n```\n\n## Real-World Use Cases\n\n### Web API Configuration\n\n```rust\n#[derive(Builder)]\nstruct ApiConfig {\n    #[builder(required)]\n    base_url: String,\n\n    #[builder(optional)]\n    use_auth: Option\u003cbool\u003e,\n\n    #[builder(required_if = \"use_auth\")]\n    api_key: Option\u003cString\u003e,\n\n    #[builder(required_if = \"use_auth\")]\n    secret: Option\u003cString\u003e,\n\n    #[builder(default = \"30\")]\n    timeout_seconds: u64,\n\n    #[builder(default = \"String::from(\\\"application/json\\\")\")]\n    content_type: String,\n}\n```\n\n### Database Connection\n\n```rust\n#[derive(Builder)]\nstruct DatabaseConfig {\n    #[builder(required)]\n    host: String,\n\n    #[builder(required)]\n    database: String,\n\n    #[builder(default = \"5432\")]\n    port: u16,\n\n    #[builder(default = \"10\")]\n    max_connections: u32,\n\n    #[builder(optional)]\n    use_ssl: Option\u003cbool\u003e,\n\n    #[builder(required_if = \"use_ssl\")]\n    ssl_cert_path: Option\u003cString\u003e,\n\n    #[builder(optional_if = \"!use_ssl\")]\n    allow_insecure: Option\u003cbool\u003e,\n}\n```\n\n## Contributing\n\nWe welcome contributions to TypeSafe Builder!\n\n### Development Environment Setup\n\n```bash\ngit clone https://github.com/tomoikey/typesafe_builder.git\ncd typesafe_builder\ncargo test\n```\n\n### Running Tests\n\n```bash\n# Run all tests\ncargo test\n\n# UI tests (compile error verification)\ncargo test --package typesafe_builder_derive --test ui\n```\n\n## Contributors\n\nAmazing developers who have contributed to this project:\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003ca href=\"https://github.com/tomoikey\"\u003e\n        \u003cimg src=\"https://github.com/tomoikey.png?size=100\" width=\"100px;\" alt=\"tomoikey\"/\u003e\n        \u003cbr /\u003e\n        \u003csub\u003e\u003cb\u003etomoikey\u003c/b\u003e\u003c/sub\u003e\n        \u003cbr /\u003e\n        \u003csub\u003eCreator \u0026 Maintainer\u003c/sub\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003ca href=\"https://github.com/ramsyana\"\u003e\n        \u003cimg src=\"https://github.com/ramsyana.png?size=100\" width=\"100px;\" alt=\"ramsyana\"/\u003e\n        \u003cbr /\u003e\n        \u003csub\u003e\u003cb\u003eramsyana\u003c/b\u003e\u003c/sub\u003e\n        \u003cbr /\u003e\n        \u003csub\u003eContributor\u003c/sub\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003ca href=\"https://github.com/tomoikey/typesafe_builder/graphs/contributors\"\u003e\n        \u003cimg src=\"https://via.placeholder.com/100x100/f0f0f0/999999?text=%3F\" width=\"100px;\" alt=\"You?\"/\u003e\n        \u003cbr /\u003e\n        \u003csub\u003e\u003cb\u003eYour Name Here\u003c/b\u003e\u003c/sub\u003e\n        \u003cbr /\u003e\n        \u003csub\u003eNext Contributor\u003c/sub\u003e\n      \u003c/a\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n*Want to see your name here? [Contribute now](https://github.com/tomoikey/typesafe_builder/blob/main/CONTRIBUTING.md) and join our amazing community!*\n\n[![Contributors](https://contrib.rocks/image?repo=tomoikey/typesafe_builder)](https://github.com/tomoikey/typesafe_builder/graphs/contributors)\n\n\u003c/div\u003e\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## Give us a star!\n\nIf you find this project useful, please consider giving it a star!\n\n---\n\n\u003cdiv align=\"center\"\u003e\n    \u003cstrong\u003eMade with ❤️ by Rust community\u003c/strong\u003e\n    \u003cbr /\u003e\n    \u003csub\u003eType safety is not a luxury, it's a necessity.\u003c/sub\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomoikey%2Ftypesafe_builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomoikey%2Ftypesafe_builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomoikey%2Ftypesafe_builder/lists"}