Skip to main content

automorph_derive/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Derive macro for the Automorph trait.
4//!
5//! This crate provides `#[derive(Automorph)]` to automatically implement
6//! bidirectional synchronization with Automerge documents.
7//!
8//! ## Supported Structures
9//!
10//! - Named structs: `struct Foo { bar: i32 }`
11//! - Tuple structs (newtype): `struct Foo(Bar)`
12//! - Unit structs: `struct Foo`
13//! - Enums with all variant types
14//!
15//! ## Container Attributes
16//!
17//! - `#[automorph(rename_all = "...")]` - Rename all fields (camelCase, snake_case, etc.)
18//! - `#[automorph(tag = "...")]` - Internal tagging for enums
19//! - `#[automorph(tag = "...", content = "...")]` - Adjacent tagging for enums
20//! - `#[automorph(untagged)]` - Untagged enum representation
21//!
22//! ## Field Attributes
23//!
24//! - `#[automorph(rename = "...")]` - Rename this field
25//! - `#[automorph(skip)]` - Skip this field entirely
26//! - `#[automorph(default)]` - Use Default if field is missing
27
28mod attribute_parsing;
29mod case_conversion;
30mod enum_derive;
31mod struct_derive;
32
33use proc_macro::TokenStream;
34use syn::{Data, DeriveInput, parse_macro_input};
35
36/// Derive the `Automorph` trait for a struct or enum.
37///
38/// # Example
39///
40/// ```ignore
41/// use automorph::Automorph;
42///
43/// #[derive(Automorph, Default, Clone)]
44/// struct Person {
45///     name: String,
46///     age: u64,
47/// }
48/// ```
49///
50/// This generates an implementation that stores the struct as an Automerge Map
51/// with each field as a key.
52#[proc_macro_derive(Automorph, attributes(automorph))]
53pub fn derive_automorph(input: TokenStream) -> TokenStream {
54    let input = parse_macro_input!(input as DeriveInput);
55
56    match &input.data {
57        Data::Struct(data) => struct_derive::derive_struct(&input, data),
58        Data::Enum(data) => enum_derive::derive_enum(&input, data),
59        Data::Union(_) => {
60            syn::Error::new(input.ident.span(), "Automorph cannot be derived for unions")
61                .to_compile_error()
62                .into()
63        }
64    }
65}