ronky/lib.rs
1//! # ๐ฑ RONKY ๐ฑ
2//!
3//! [](https://crates.io/crates/ronky)
4//! [](https://github.com/modiimedia/arri)
5//! [](https://github.com/modiimedia/arri)
6//! [](https://github.com/modiimedia/arri)
7//!
8//! _"Converting Rust types shouldn't be this purr-fect, but here we are..."_
9//!
10//! ## ๐บ What in the Whiskers is Ronky?
11//!
12//! Imagine if your Rust types could speak other languages without learning a single foreign word.
13//! That's Ronky โ your code's personal polyglot translator that speaks fluent
14//! [Arri](https://github.com/modiimedia/arri), turning your carefully crafted Rust types into
15//! schemas that even JavaScript developers can understand.
16//!
17//! Born from the frustration of manual schema creation (and named after a particularly vocal cat),
18//! Ronky does the tedious work so you can focus on the important stuff โ like deciding whether your
19//! next variable should be called `data` or `info` (we both know you'll pick `data`).
20//!
21//! > ๐ง **Paws at Work**: Like a cat that's not quite finished knocking everything off your desk,
22//! > Ronky is still under construction. Object serialization and deserialization are coming soon,
23//! > probably right after this catnap. ๐ง
24//!
25//! ## โจ Features That Make You Go "Meow!"
26//!
27//! Ronky doesn't just toss your types over the fence to Arri-land. It crafts them with the same
28//! attention to detail that a cat gives to knocking your most precious possessions off shelves:
29//!
30//! ```text
31//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
32//! โ RONKY'S REPERTOIRE โ
33//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
34//! โ ๐งฌ Type Wizardry โ - Transforms primitives with grace โ
35//! โ โ - Handles generic types without whining โ
36//! โ โ - Makes associated types feel welcome โ
37//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
38//! โ ๐งฉ Collection Conjuring โ - Vectors become elegant "elements" โ
39//! โ โ - Maps manifest as "values" schemas โ
40//! โ โ - Optional types know when to disappear โ
41//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
42//! โ ๐ก๏ธ Guardian Features โ - Strict mode keeps schemas pristine โ
43//! โ โ - Discriminators tag unions properly โ
44//! โ โ - Circular refs handled without dizziness โ
45//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
46//! โ ๐ Transformation Magic โ - Case transformations (snake โ UPPER) โ
47//! โ โ - Field renaming for multilingual joy โ
48//! โ โ - Nullable marking for optional presence โ
49//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
50//! โ ๐ Documentation Delight โ - Comments become documentation โ
51//! โ โ - Deprecation warnings that don't nag โ
52//! โ โ - Metadata that brings joy to readers โ
53//! โโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
54//! ```
55//!
56//! With Ronky, your type schema generation is both:
57//! 1. **Compile-time verified** - Errors at compile time, not at 3 AM when you're deploying
58//! 2. **Automatically generated** - Because life's too short to manually update schemas
59//!
60//! > ๐ก **Pro Tip**: Ronky's powers grow with your documentation. The more doc comments you add,
61//! > the more magnificent your schemas become. It's like feeding treats to a cat โ the rewards
62//! > are well worth it.
63//!
64//! ## ๐ค The Cool Cats Club (Compatible Crates)
65//!
66//! Ronky has an extensive social network. Think of these crates as the neighborhood cats that
67//! regularly visit your backyard โ they're all welcome and get special treatment:
68//!
69//! ```text
70//! TEMPORAL FRIENDS ๐ฐ๏ธ chrono, time
71//! IDENTITY SPECIALISTS ๐ชช uuid
72//! BIG NUMBER EXPERTS ๐ข bigdecimal, num-bigint, num-bigfloat
73//! PRECISION MASTERS ๐ฐ rust_decimal, decimal
74//! WEB-SAVVY NAVIGATORS ๐ url
75//! DATA-HANDLING WIZARDS ๐ bytes
76//! CONCURRENT COMPANIONS ๐งต dashmap
77//! ORDERLY ORGANIZERS ๐ indexmap
78//! OPTIMIZED PERFORMERS โก smallvec
79//! ```
80//!
81//! Each of these crates gets the VIP (Very Important Purring) treatment from Ronky. Their types
82//! are handled with the care and respect they deserve.
83//!
84//! > ๐ **Missing your favorite companion?** Open an issue to suggest a new addition to Ronky's
85//! > compatible crates collection. The more the merrier!
86//!
87//! ## ๐จโ๐ป The Story Behind Ronky
88//!
89//! Let me share the real origin story โ Ronky wasn't born from late-night caffeine-fueled frustration
90//! (though there's been plenty of that in my coding career). It all started when a friend dropped a
91//! Discord message with a link to the [Arri project](https://github.com/modiimedia/arri). One look at
92//! what Arri was doing with type conversions and I was hooked.
93//!
94//! As a passionate Rustacean, I immediately thought: "This is brilliant! But it needs Rust support."
95//! And thus Ronky was born โ creating a bridge between the elegant type system of Rust and the universal
96//! schema language of Arri.
97//!
98//! I named it after my cat not just because he was adorable (though he absolutely was), but because
99//! he embodied what good libraries should be โ helpful, reliable, and occasionally surprising you
100//! with something delightful. Like Ronky the cat finding innovative ways to get treats without
101//! moving, Ronky the library finds ways to update your API schemas without you lifting a finger.
102//!
103//! My hope is that this library saves you time, prevents those pesky "the API contract changed but
104//! the docs didn't" bugs, and maybe โ just maybe โ frees up enough of your day to spend time with
105//! your own four-legged friend (or fish, or rubber duck - whatever brings you joy).
106//!
107//! ## ๐ The Illustrated Guide to Ronky
108//!
109//! ### ๐ The Basic Transformation
110//!
111//! ```rust,ignore
112//! use ronky::{Exportable, Exported, SCHEMA_VERSION};
113//! use serde_json::{Value, from_str, to_string_pretty};
114//!
115//! // Just add water (and a derive macro)
116//! #[derive(Exported)]
117//! #[arri(transform = "uppercase")] // LOUD NOISES
118//! enum Result<T: Exportable, E: Exportable> {
119//! /// When things go right (rarely, if you're me)
120//! Ok(T),
121//! /// When things go wrong (my default state)
122//! Err(E),
123//! }
124//!
125//!
126//! // Announce our intentions to the world
127//! println!("๐งช Creating an Arri {} schema and hoping for the best...", SCHEMA_VERSION);
128//!
129//! // The cat-alchemy happens here
130//! let schema_json = Result::<String, ()>::export()
131//! .serialize()
132//! .expect("this to work (please, I have deadlines)");
133//!
134//! // Humans like pretty things
135//! let pretty_json = to_string_pretty(&from_str::<Value>(&schema_json).unwrap()).unwrap();
136//!
137//! // Admire our handiwork
138//! println!("{}", pretty_json);
139//!
140//! // Now go make a cup of tea, you've earned it
141//! ```
142//!
143//! ### ๐งฉ The Advanced Cat-egory: Building Complex Types
144//!
145//! ```rust,ignore
146//! use ronky::{Exportable, Exported, SCHEMA_VERSION};
147//!
148//! /// Metadata about things (and sometimes other things)
149//! #[derive(Exported)]
150//! struct About<T: Exportable> {
151//! /// What we called it before marketing got involved
152//! #[deprecated(since = "1.0.0", note = "Use `firstName` and `lastName` instead")]
153//! name: String,
154//!
155//! /// The name that appears on your coffee cup at Starbucks
156//! first_name: String,
157//!
158//! /// The name your parents use when you're in trouble
159//! last_name: Option<String>,
160//!
161//! /// The number that makes you sigh at birthday parties
162//! age: u32,
163//!
164//! /// The subject of our obsession
165//! of: T,
166//! }
167//!
168//! /// A creature that creates Rust crates, ironically
169//! #[derive(Exported)]
170//! #[arri(strict)] // No surprises allowed! Like a cat with a cucumber
171//! struct Human {
172//! /// Fellow code-monkeys who review your PRs
173//! friends: Vec<Human>, // Recursive types? No problem!
174//!
175//! /// The real owners of your home
176//! pets: Vec<About<Pet>>,
177//! }
178//!
179//! /// Fashion choices for the discerning feline
180//! #[derive(Exported)]
181//! #[arri(transform = ["snake_case", "uppercase"])] // MULTI_STYLE_TRANSFORMATION
182//! enum CatColor {
183//! /// Like my coffee and my humor
184//! Black,
185//!
186//! /// Like my documentation standards and error handling
187//! White,
188//!
189//! /// Like my moral compass when it comes to optimization
190//! Gray,
191//!
192//! /// Like my commit history after a weekend hackathon
193//! MixedGrayWhite,
194//! }
195//!
196//! /// Entities that interrupt your Zoom calls at the worst possible moment
197//! #[derive(Exported)]
198//! #[arri(transform = "uppercase", discriminator = "species")]
199//! enum Pet {
200//! Dog {
201//! /// The word you'll repeat 37 times at the dog park
202//! name: String,
203//!
204//! /// What you'll forget when the vet asks
205//! #[arri(nullable)]
206//! breed: Option<String>,
207//! },
208//!
209//! #[arri(rename = "cat")] // All hail the cat overlords!
210//! Lion {
211//! /// A suggestion they might consider responding to someday
212//! name: String,
213//!
214//! /// Their royal garment
215//! #[arri(nullable)]
216//! color: Option<CatColor>,
217//! },
218//! }
219//! ```
220//!
221//! > ๐ฅ **Hot Tip**: These examples aren't just decorative โ they're functional!
222//! > Copy, paste, and experience the magic of Ronky firsthand. Your future self
223//! > will thank you when your API documentation is automatically up-to-date.
224//!
225//! ## ๐ The Ronky Memorial Section
226//!
227//! ```text
228//! /\_/\
229//! ( o.o )
230//! > ^ <
231//! / O \ "Meow meow, transform types meow."
232//! - Ronky (2010-2024)
233//! ```
234//!
235//! This library immortalizes a magnificent cat named Ronky, whose thunderous purrs
236//! (or "ronks" in Dutch) could wake the neighbors. For 14 remarkable years, this
237//! whiskered genius supervised everything that happened in the house.
238//!
239//! Despite battling acromegaly, Ronky maintained a proud dignity and an uncanny ability
240//! to walk across keyboards. His legacy continues in this library!
241//!
242//! Ronky taught me important programming principles:
243//!
244//! - **Persistence**: If at first you don't succeed, meow louder until someone fixes it for you
245//! - **Efficiency**: Why do something yourself when you can delegate?
246//! - **Work-Life Balance**: No bug is so important that it can't wait until after a nap
247//! - **Code Reviews**: Sometimes the best feedback is just silently judging from a distance
248//!
249//! This library aims to embody these principles by automating the tedious parts of
250//! API development so you can focus on the parts that matter โ like figuring out why
251//! your application works in development but not production (it's always CORS).
252//!
253//! ## ๐ Quick Reference
254//!
255//! ### The Basics
256//!
257//! 1. Add `ronky` to your `Cargo.toml`:
258//! ```toml
259//! [dependencies]
260//! ronky = "1.0.0" # Check crates.io for the latest version
261//! ```
262//!
263//! 2. Import the essentials:
264//! ```rust,ignore
265//! use ronky::{Exported, SCHEMA_VERSION};
266//! ```
267//!
268//! 3. Decorate your types:
269//! ```rust,ignore
270//! #[derive(Exported)]
271//! struct MyType { /* fields */ }
272//! ```
273//!
274//! 4. Export and serialize:
275//! ```rust,ignore
276//! let schema = MyType::export().serialize().unwrap();
277//! ```
278//!
279//! 5. Profit! (This step is not automated by Ronky, sorry)
280//!
281//! ### Attribute Options
282//!
283//! - `#[arri(strict)]` - No extra properties allowed
284//! - `#[arri(transform = "snake_case")]` - Transform enum variant names
285//! - `#[arri(discriminator = "type")]` - Set discriminator field name
286//! - `#[arri(rename = "newName")]` - Rename a field or variant
287//! - `#[arri(nullable)]` - Mark a field as nullable
288//!
289//! ## ๐ Final Thought
290//!
291//! Remember: Type conversion should be like a cat's nap โ automatic, elegant, and requiring
292//! no effort on your part. Let Ronky handle the tedious work while you focus on building
293//! something amazing.
294//!
295//! Now go pet your cat (or dog, or rubber duck) โ they've been waiting patiently while you
296//! read this documentation. โค๏ธ
297
298#[cfg(feature = "serialization")]
299mod serialization;
300
301#[cfg(feature = "derive")]
302extern crate ronky_derive;
303
304#[cfg(feature = "derive")]
305pub use ronky_derive::Exported;
306
307extern crate arri_repr;
308pub use arri_repr::*;
309
310#[cfg(feature = "serialization")]
311pub use serialization::{ExportedDeserialize, ExportedSerialize};
312
313pub static SCHEMA_VERSION: &str = "v0.0.8";
314
315// TODO: implement conversion from ATD to Rust types
316// | ATD Type | Rust Type |
317// |---|---|
318// | string | String |
319// | boolean | bool |
320// | timestamp | DateTime |
321// | float32 | f32 |
322// | float64 | f64 |
323// | int8 | i8 |
324// | uint8 | u8 |
325// | int16 | i16 |
326// | uint16 | u16 |
327// | int32 | i32 |
328// | uint32 | u32 |
329// | int64 | i64 |
330// | uint64 | u64 |