{"id":24475812,"url":"https://github.com/arthurdw/ronky","last_synced_at":"2026-03-11T11:39:11.824Z","repository":{"id":248004670,"uuid":"826919313","full_name":"Arthurdw/ronky","owner":"Arthurdw","description":"Compile time Rust types to Arri schemas, with purr-fect precision","archived":false,"fork":false,"pushed_at":"2026-03-04T14:53:07.000Z","size":1025,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-04T16:20:42.601Z","etag":null,"topics":["arri","deserialisation","rpc","serialisation"],"latest_commit_sha":null,"homepage":"https://docs.rs/ronky","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Arthurdw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-07-10T16:36:14.000Z","updated_at":"2026-03-04T14:54:23.000Z","dependencies_parsed_at":"2024-07-11T21:34:16.989Z","dependency_job_id":"9c128d23-5251-41bb-908b-37a7c9657e96","html_url":"https://github.com/Arthurdw/ronky","commit_stats":null,"previous_names":["arthurdw/ronky","arthurdw/rs-exporter"],"tags_count":97,"template":false,"template_full_name":null,"purl":"pkg:github/Arthurdw/ronky","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arthurdw%2Fronky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arthurdw%2Fronky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arthurdw%2Fronky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arthurdw%2Fronky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Arthurdw","download_url":"https://codeload.github.com/Arthurdw/ronky/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arthurdw%2Fronky/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30380081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-11T06:09:32.197Z","status":"ssl_error","status_checked_at":"2026-03-11T06:09:17.086Z","response_time":84,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["arri","deserialisation","rpc","serialisation"],"created_at":"2025-01-21T09:42:53.288Z","updated_at":"2026-03-11T11:39:11.817Z","avatar_url":"https://github.com/Arthurdw.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐱 RONKY 🐱\n\n[![Crates.io Version](https://img.shields.io/crates/v/ronky)](https://crates.io/crates/ronky)\n[![Purrs Per Minute](https://img.shields.io/badge/purrs-over%209000-orange)](https://github.com/modiimedia/arri)\n[![Cat Approved](https://img.shields.io/badge/cat-approved-brightgreen)](https://github.com/modiimedia/arri)\n[![Rustacean Friendly](https://img.shields.io/badge/rustacean-friendly-blue)](https://github.com/modiimedia/arri)\n\n_\"Converting Rust types shouldn't be this purr-fect, but here we are...\"_\n\n## 😺 What in the Whiskers is Ronky?\n\nImagine if your Rust types could speak other languages without learning a single foreign word.\nThat's Ronky – your code's personal polyglot translator that speaks fluent\n[Arri](https://github.com/modiimedia/arri), turning your carefully crafted Rust types into\nschemas that even JavaScript developers can understand.\n\nBorn from the frustration of manual schema creation (and named after a particularly vocal cat),\nRonky does the tedious work so you can focus on the important stuff – like deciding whether your\nnext variable should be called `data` or `info` (we both know you'll pick `data`).\n\n\n\u003c!--toc:start--\u003e\n\n- [🐱 RONKY 🐱](#-ronky-)\n  - [😺 What in the Whiskers is Ronky?](#-what-in-the-whiskers-is-ronky)\n  - [✨ Features That Make You Go \"Meow!\"](#-features-that-make-you-go-meow)\n  - [🤝 The Cool Cats Club (Compatible Crates)](#-the-cool-cats-club-compatible-crates)\n  - [📚 The Illustrated Guide to Ronky](#-the-illustrated-guide-to-ronky)\n    - [🔄 The Basic Transformation](#-the-basic-transformation)\n    - [🧩 The Advanced Cat-egory: Building Complex Types](#-the-advanced-cat-egory-building-complex-types)\n  - [📋 Quick Reference](#-quick-reference)\n    - [The Basics](#the-basics)\n    - [Attribute Options](#attribute-options)\n  - [🐈 The Ronky Memorial Section](#-the-ronky-memorial-section)\n  - [🛠️ Development](#️-development)\n    - [Pre-commit Hooks](#pre-commit-hooks)\n    - [Running Tests](#running-tests)\n    - [Code Quality Checks](#code-quality-checks)\n  - [🌟 Final Thought](#-final-thought)\n  \u003c!--toc:end--\u003e\n\n## ✨ Features That Make You Go \"Meow!\"\n\nRonky doesn't just toss your types over the fence to Arri-land. It crafts them with the same\nattention to detail that a cat gives to knocking your most precious possessions off shelves:\n\n```text\n┌───────────────────────────────────────────────────────────────────────┐\n│                          RONKY'S REPERTOIRE                           │\n├───────────────────────────┬───────────────────────────────────────────┤\n│ 🧬 Type Wizardry          │ - Transforms primitives with grace        │\n│                           │ - Handles generic types without whining   │\n│                           │ - Makes associated types feel welcome     │\n├───────────────────────────┼───────────────────────────────────────────┤\n│ 🧩 Collection Conjuring   │ - Vectors become elegant \"elements\"       │\n│                           │ - Maps manifest as \"values\" schemas       │\n│                           │ - Optional types know when to disappear   │\n├───────────────────────────┼───────────────────────────────────────────┤\n│ 🛡️ Guardian Features      │ - Strict mode keeps schemas pristine      │\n│                           │ - Discriminators tag unions properly      │\n│                           │ - Circular refs handled without dizziness │\n├───────────────────────────┼───────────────────────────────────────────┤\n│ 🔄 Transformation Magic   │ - Case transformations (snake → UPPER)    │\n│                           │ - Field renaming for multilingual joy     │\n│                           │ - Nullable marking for optional presence  │\n├───────────────────────────┼───────────────────────────────────────────┤\n│ 📝 Documentation Delight  │ - Comments become documentation           │\n│                           │ - Deprecation warnings that don't nag     │\n│                           │ - Metadata that brings joy to readers     │\n└───────────────────────────┴───────────────────────────────────────────┘\n```\n\nWith Ronky, your type schema generation is both:\n\n1. **Compile-time verified** - Errors at compile time, not at 3 AM when you're deploying\n2. **Automatically generated** - Because life's too short to manually update schemas\n\n\u003e 💡 **Pro Tip**: Ronky's powers grow with your documentation. The more doc comments you add,\n\u003e the more magnificent your schemas become. It's like feeding treats to a cat – the rewards\n\u003e are well worth it.\n\n## 🤝 The Cool Cats Club (Compatible Crates)\n\nRonky has an extensive social network. Think of these crates as the neighborhood cats that\nregularly visit your backyard – they're all welcome and get special treatment:\n\n```text\nTEMPORAL FRIENDS         🕰️  chrono, time\nIDENTITY SPECIALISTS     🪪  uuid\nBIG NUMBER EXPERTS       🔢  bigdecimal, num-bigint, num-bigfloat\nPRECISION MASTERS        💰  rust_decimal, decimal\nWEB-SAVVY NAVIGATORS     🌐  url\nDATA-HANDLING WIZARDS    📊  bytes\nCONCURRENT COMPANIONS    🧵  dashmap\nOPTIMIZED PERFORMERS     ⚡  smallvec\nDYNAMIC SHAPESHIFTERS    🔮  any (Value type for arbitrary JSON)\n```\n\nEach of these crates gets the VIP (Very Important Purring) treatment from Ronky. Their types\nare handled with the care and respect they deserve.\n\n\u003e 🐈 **Missing your favorite companion?** Check if an issue exists, and if not, create one!\n\u003e The more the merrier in Ronky's compatible crates collection.\n\n## 📚 The Illustrated Guide to Ronky\n\n### 🔄 The Basic Transformation\n\n```rust\nuse ronky::{Exportable, Exported, SCHEMA_VERSION};\nuse serde_json::{Value, from_str, to_string_pretty};\n\n// Just add water (and a derive macro)\n#[derive(Exported)]\n#[arri(transform = \"uppercase\")] // LOUD NOISES\nenum Result\u003cT: Exportable, E: Exportable\u003e {\n    /// When things go right (rarely, if you're me)\n    Ok(T),\n    /// When things go wrong (my default state)\n    Err(E),\n}\n\nfn main() {\n    // Announce our intentions to the world\n    println!(\"🧪 Creating an Arri {} schema and hoping for the best...\", SCHEMA_VERSION);\n\n    // The cat-alchemy happens here\n    let schema_json = Result::\u003cString, ()\u003e::export()\n        .serialize()\n        .expect(\"this to work (please, I have deadlines)\");\n\n    // Humans like pretty things\n    let pretty_json = to_string_pretty(\u0026from_str::\u003cValue\u003e(\u0026schema_json).unwrap()).unwrap();\n\n    // Admire our handiwork\n    println!(\"{}\", pretty_json);\n\n    // Now go make a cup of tea, you've earned it\n}\n```\n\n### 🧩 The Advanced Cat-egory: Building Complex Types\n\n```rust\nuse ronky::{Exportable, Exported, SCHEMA_VERSION};\n\n/// Metadata about things (and sometimes other things)\n/// Automatically converts snake_case field names to camelCase for the schema\n#[derive(Exported)]\n#[arri(rename_all = \"camelCase\")] // firstName, lastName, etc. in the schema\nstruct About\u003cT: Exportable\u003e {\n    /// What we called it before marketing got involved\n    #[deprecated(since = \"1.0.0\", note = \"Use `firstName` and `lastName` instead\")]\n    name: String,\n\n    /// The name that appears on your coffee cup at Starbucks\n    first_name: String, // Becomes \"firstName\" in the schema\n\n    /// The name your parents use when you're in trouble\n    last_name: Option\u003cString\u003e, // Becomes \"lastName\" in the schema\n\n    /// The number that makes you sigh at birthday parties\n    age: u32,\n\n    /// The subject of our obsession\n    of: T,\n}\n\n/// A creature that creates Rust crates, ironically\n#[derive(Exported)]\n#[arri(strict)] // No surprises allowed! Like a cat with a cucumber\nstruct Human {\n    /// Fellow code-monkeys who review your PRs\n    friends: Vec\u003cHuman\u003e, // Recursive types? No problem!\n\n    /// The real owners of your home\n    pets: Vec\u003cAbout\u003cPet\u003e\u003e,\n}\n\n/// Fashion choices for the discerning feline\n#[derive(Exported)]\n#[arri(transform = [\"snake_case\", \"uppercase\"])] // MULTI_STYLE_TRANSFORMATION\nenum CatColor {\n    /// Like my coffee and my humor\n    Black,\n\n    /// Like my documentation standards and error handling\n    White,\n\n    /// Like my moral compass when it comes to optimization\n    Gray,\n\n    /// Like my commit history after a weekend hackathon\n    MixedGrayWhite,\n}\n\n/// Entities that interrupt your Zoom calls at the worst possible moment\n#[derive(Exported)]\n#[arri(transform = \"uppercase\", discriminator = \"species\")]\nenum Pet {\n    Dog {\n        /// The word you'll repeat 37 times at the dog park\n        name: String,\n\n        /// What you'll forget when the vet asks\n        #[arri(nullable)]\n        breed: Option\u003cString\u003e,\n    },\n\n    #[arri(rename = \"cat\")] // All hail the cat overlords!\n    Lion {\n        /// A suggestion they might consider responding to someday\n        name: String,\n\n        /// Their royal garment\n        #[arri(nullable)]\n        color: Option\u003cCatColor\u003e,\n    },\n}\n```\n\n\u003e 🔥 **Hot Tip**: These examples aren't just decorative – they're functional!\n\u003e Copy, paste, and experience the magic of Ronky firsthand. Your future self\n\u003e will thank you when your API documentation is automatically up-to-date.\n\n### 🔮 The Dynamic Shapeshifter: Working with Any Type\n\nSometimes you need to handle arbitrary JSON data without knowing its structure at compile time.\nEnable the `any` feature (along with `derive` for the macro) and use the `Value` type:\n\n```toml\nronky = { version = \"1.2.8\", features = [\"derive\", \"any\"] }\n```\n\n```rust\nuse ronky::{Exported, Value, NumberValue};\nuse std::collections::BTreeMap;\n\n/// A configuration that accepts arbitrary metadata\n#[derive(Exported)]\nstruct Config {\n    /// The name of this configuration\n    name: String,\n\n    /// Arbitrary metadata - could be anything!\n    /// Exports to an empty Arri schema `{}` which accepts any JSON value\n    metadata: Value,\n}\n\nfn main() {\n    // Create dynamic values\n    let mut meta = BTreeMap::new();\n    meta.insert(\"version\".to_string(), Value::Number(NumberValue::PosInt(42)));\n    meta.insert(\"enabled\".to_string(), Value::Bool(true));\n    meta.insert(\"tags\".to_string(), Value::Array(vec![\n        Value::String(\"production\".to_string()),\n        Value::String(\"critical\".to_string()),\n    ]));\n\n    let config = Config {\n        name: \"my-service\".to_string(),\n        metadata: Value::Object(meta),\n    };\n\n    // The schema exports `metadata` as `{}` - accepts any JSON value\n    let schema = Config::export().serialize().unwrap();\n}\n```\n\n\u003e 🐱 **Note**: The `Value` type maps to Arri's \"Empty Schema Form\" (`{}`), which accepts\n\u003e any JSON value. This is equivalent to `any` in TypeScript or `interface{}` in Go.\n\n## 📋 Quick Reference\n\n### The Basics\n\n1. Add `ronky` to your `Cargo.toml`:\n\n   ```toml\n   [dependencies]\n   ronky = { version = \"1.2.8\", features = [\"derive\"] }\n   ```\n\n   The `derive` feature enables the `#[derive(Exported)]` macro. Additional features can be enabled as needed:\n\n   ```toml\n   [dependencies]\n   ronky = { version = \"1.2.8\", features = [\"derive\", \"chrono\", \"uuid\", \"any\"] }\n   ```\n\n2. Import the essentials:\n\n   ```rust\n   use ronky::{Exported, SCHEMA_VERSION};\n   ```\n\n3. Decorate your types:\n\n   ```rust\n   #[derive(Exported)]\n   struct MyType { /* fields */ }\n   ```\n\n4. Export and serialize:\n\n   ```rust\n   let schema = MyType::export().serialize().unwrap();\n   ```\n\n5. Profit! (This step is not automated by Ronky, sorry)\n\n### Attribute Options\n\n**Struct-level attributes:**\n- `#[arri(strict)]` - No extra properties allowed\n- `#[arri(rename_all = \"camelCase\")]` - Transform all field names to a specific case\n  - Supported cases: `camelCase`, `PascalCase`, `snake_case`, `SCREAMING_SNAKE_CASE`, `kebab-case`, `SCREAMING-KEBAB-CASE`\n- `#[arri(transform = \"snake_case\")]` - Transform enum variant names (enums only)\n- `#[arri(discriminator = \"type\")]` - Set discriminator field name (tagged unions only)\n\n**Field-level attributes:**\n- `#[arri(rename = \"newName\")]` - Rename a specific field or variant (overrides `rename_all`)\n- `#[arri(nullable)]` - Mark a field as nullable\n\n## 🐈 The Ronky Memorial Section\n\n```text\n     /\\_/\\\n    ( o.o )\n     \u003e ^ \u003c\n    /  O  \\  \"Meow meow, transform types meow.\"\n                                    - Ronky (2010-2024)\n```\n\nThis library immortalizes a magnificent cat named Ronky, named for his thunderous purrs\n(or \"ronks\" in Dutch). For 14 remarkable years, this whiskered genius supervised\neverything that happened in the house.\n\nDespite battling acromegaly, Ronky maintained a proud dignity and an uncanny ability\nto walk across keyboards and make his presence known. His legacy continues in this library!\n\nHe passed away peacefully, surrounded by those who loved him, and will be deeply missed.\n\n![A beautiful picture of Ronky](./.readme/assets/ronky.jpg)\nPhoto by [Startshot](https://www.instagram.com/_startshot_/)\n\n## 🛠️ Development\n\n### Pre-commit Hooks\n\nThis project uses pre-commit hooks to maintain code quality. We support both `pre-commit` and `prek` (a Rust implementation that uses the same `.pre-commit-config.yaml` format).\n\n**Auto-fixing**: The hooks automatically fix formatting issues, clippy warnings, trailing whitespace, and line endings. See [docs/AUTO_FIXING.md](docs/AUTO_FIXING.md) for details.\n\n#### Using prek (Recommended for Rust projects)\n\n`prek` is a Rust-based pre-commit hook runner that uses the standard `.pre-commit-config.yaml` configuration file.\n\n```bash\n# Install prek (if not already installed)\ncargo install prek\n\n# Install hooks\nprek install\n\n# Run all hooks manually\nprek run --all-files\n\n# Run specific hook\nprek run cargo-fmt\n```\n\n#### Using pre-commit\n\n```bash\n# Install pre-commit\npip install pre-commit\n\n# Install hooks\npre-commit install\n\n# Run all hooks manually\npre-commit run --all-files\n```\n\n### Running Tests\n\n```bash\n# Run all tests with nextest\ncargo nextest run --all\n\n# Run specific test\ncargo nextest run serialization_export\n\n# Run with standard cargo test\ncargo test --all\n```\n\n### Code Quality Checks\n\n```bash\n# Format code\ncargo fmt --all\n\n# Run clippy\ncargo clippy --all-features --all-targets -- -D warnings\n\n# Check compilation\ncargo check --all --all-features\n\n# Run all checks at once\n./scripts/pre-commit-all.sh\n```\n\n## 🌟 Final Thought\n\nRemember: Type conversion should be like a cat's nap – automatic, elegant, and requiring\nno effort on your part. Let Ronky handle the tedious work while you focus on building\nsomething amazing.\n\nNow go pet your cat (or dog, or rubber duck) – they've been waiting patiently while you\nread this documentation. ❤️\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurdw%2Fronky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farthurdw%2Fronky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurdw%2Fronky/lists"}