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