josephg/diamond-types

Derive macro for complex data-structures?

nickdbush opened this issue · 0 comments

As support for a wider array of data structures grows in diamond types, would a derive macro be worth it? For example, the shelf merging algorithm that I contributed a few months ago could be derived for a struct without too much bother, and CRDTs for other data structures (e.g. strings and lists) could be swapped in with attributes. In essence, I think it would be interesting if we could make something similar to the following happen:

#[derive(CRDT)]
struct Article {
    #[crdt(algo = "rich")]
    content: String,
    #[crdt(algo = "list")]
    tags: Vec<String>,
    slug: String,
    is_ready: bool
}

This would apply shelf logic to the is_ready and slug field (e.g. last write wins) and apply CRDT logic to the list of tags and setup the content field for collaborative rich-text merging. Perhaps it would produce something like:

enum ArticleShelfType {
    String(String),
    Bool(bool)
}

struct ArticleCrdt {
    content: TextCrdt,
    tags: ListCrdt,
    slug: shelf::Item<ArticleShelfType>,
    is_ready: shelf::Item<ArticleShelfType>,
}

impl Into<Shelf<ArticleShelfType>> for ArticleCrdt {
    fn into(self) -> Shelf<ArticleShelfType> {
        // ...
    }
}

impl ArticleCrdt {
    // Generate methods for merging two Article structs.
    // Fields with specific CRDT algos are merged using those rules.
    // All other fields are merged using the shelf algorithm.
}

This is my first stab at an API interface without any significant thought into what it would need to look like – I'd like to test the water first and see if this is a direction in which this library wants to go. I'd be happy to hack around with the process if it's something that would be worth exploring! I think it would break the barrier of entry for CRDTs and provide a comfortable on-ramp for developers to include them in a wider variety of projects (long live collaborative applications!).