Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ToKey implementation for Serializable types. #219

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

majkrzak
Copy link

@majkrzak majkrzak commented Sep 1, 2024

I have encountered a problem, where I wanted to use third-party type as a primary key. Thanks to Rust policy against orphans, it is not possible to implement ToKey trait for it.

As the type I wanted to use was serde compatible, I implemented generic ToKey for serde::Serialize types:

impl<T: Serialize + Debug> ToKey for T {
    fn to_key(&self) -> Key {
        let mut serializer = KeySerializer::new();
        self.serialize(&mut serializer).unwrap();
        serializer.into()
    }
}

Together with KeySerializer, which is backward compatible with the old implementation.

It covers wider range of types, and therefore some assumption how some types have to be processed were made. In particular enum types are serialized by their option indexes. This require from end-user to extend such types in specific way to keep backward compatibility.

Additionally, I believe, if this could ever made its way to the main branch following things have to be handled:

  • wrap in opt-in package feature
  • expand documentation
  • write some tests covering design decisions
  • cleanup interface

@majkrzak majkrzak marked this pull request as draft September 1, 2024 19:28
@vincent-herlemont
Copy link
Owner

Thank you very much, @majkrzak, for your suggestion. It's very interesting; however, I'm concerned that using Serde might create some overhead. I am currently working on improving the benchmarks to determine if such changes would cause any performance loss.

BTW, could you tell me a bit more about your initial problem? It is possible to use a type wrapper, for example with UUIDs here: struct Uuid(uuid::Uuid); src/db_type/key/key.rs#L76-L110. By using a type wrapper, you should normally be able to associate an interface with any third-party type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants