Add support for newtype-uuid? #3993
Replies: 1 comment 4 replies
-
Thanks for opening this discussion. We usually use the following points to decide whether to add support for a certain rust <-> sql type mapping in diesel itself:
I think the first three points a fulfilled given that this seems to be just a wrapper around the uuid crate. That said I'm not sure that I would call a crate with ~1000 daily downloads as widely used (compared to the > 100.000 daily downloads for uuid). I personally would tend to the first variant from your suggestion list. My main concern here is maintainer capacity. There is only that much code that I can maintaining the limited amount of time I have for this project and I would rather spend that code budget on widely used features. I agree on the general observation that the orphan rule sometimes gets in your way, but I fear there is no easy solution to this problem. (As far as I'm aware other solutions do not have that specific limitation, but will result into other equally bad problems). |
Beta Was this translation helpful? Give feedback.
-
Hi there,
I'm the primary maintainer of newtype-uuid, a crate which provides type-level annotations to UUIDs via a
TypedUuid
wrapper, so that we can avoid mixing them up. It's a relatively new crate, but one that we've had a lot of success with at Oxide. There's nothing else quite like it in the Rust ecosystem (the closest crate is typed-uuid which is different in certain ways) and I think newtype-uuid is a broadly useful crate.We plan to keep
newtype-uuid
at v1 forever, adding new features to it in an append-only fashion.Ideally we'd be able to use
TypedUuid
instances directly in Diesel structs. But as you're aware, Rust's orphan rules get in the way of that. I can think of four possible solutions to this, though I'm happy to hear of more ideas:newtype-uuid
implement Diesel's traitsDbTypedUuid<T>(pub TypedUuid<T>)
, which impls Diesel's traits.Going through each of the possible options:
The biggest problem with 1 is that it is committal: it will not be possible to change this in the future without making a breaking change to either
newtype-uuid
or Diesel, to the best of my knowledge. Also, it means that none of Diesel's dependencies would ever be able to pull in newtype-uuid in the future -- the position of newtype-uuid "above" Diesel and its dependencies will be solidified forever.Logically,
newtype-uuid
is a thin wrapper around uuid, and so is "small" in a similar way, while Diesel is "large". It would generally be nice for "large" dependencies to pull in "small" ones rather than the other way round. None of newtype-uuid's dependencies are ever realistically going to pull in Diesel, but the other way round is quite possible.2 is what I'm proposing here. The largest issue is just figuring out whether the crate is broadly useful enough, which is certainly a judgment call -- but one that I submit has a clear answer in this case.
3 is what we've been trying to do at Oxide so far and it's certainly possible, but has had some serious issues along the way. It ends up being quite awkward to convert back and forth. For example, it's not just structs that define DB records -- queries need to convert back and forth from
DbTypedUuid
toTypedUuid
. It's ranged from mildly annoying to outright terrible in practice -- so much so that in a few spots we've given up on having typed UUIDs.4 is definitely an option we've considered, but maintaining a patchset in perpetuity can be a lot of work. In addition to that, we'd want to use a
[patch]
directive to pull it in, so that we can leverage the rest of the Diesel ecosystem while making this append-only change. This means that it isn't possible to publish code that depends on this to crates.io. ([patch.crates-io]
requires that the package be named the same -- there's an open issue for this).So based on the above description, it would be nice if Diesel grew support for newtype-uuid. I'm happy to do the work here if this sounds good.
This, and other similar issues, have solidified my general opinion that the current way orphan rules play out in the ecosystem is, by some margin, the worst part of Rust. I have some thoughts on how to relax the orphan rules in a principled way that keeps API compat and avoids the failure mode of Haskell's
{-# LANGUAGE UndecidableInstances #-}
, and hope to publish and start advocating for them soon.Beta Was this translation helpful? Give feedback.
All reactions