@@ -298,6 +298,82 @@ impl<T: TypedUuidKind> TypedUuid<T> {
298298 pub fn get_version ( & self ) -> Option < Version > {
299299 self . uuid . get_version ( )
300300 }
301+
302+ /// Converts the UUID to one with a different kind.
303+ ///
304+ /// By default, UUID kinds are considered independent, and conversions
305+ /// between them must happen via the [`GenericUuid`] interface. But in some
306+ /// cases, there may be a relationship between two different UUID kinds, and
307+ /// you may wish to easily convert UUIDs from one kind to another.
308+ ///
309+ /// Typically, a conversion from `TypedUuid<T>` to `TypedUuid<U>` is most
310+ /// useful when `T`'s semantics are a superset of `U`'s, or in other words,
311+ /// when every `TypedUuid<T>` is logically also a `TypedUuid<U>`.
312+ ///
313+ /// For instance:
314+ ///
315+ /// * Imagine you have [`TypedUuidKind`]s for different types of
316+ /// database connections, where `DbConnKind` is the general type
317+ /// and `PgConnKind` is a specific kind for Postgres.
318+ /// * Since every Postgres connection is also a database connection,
319+ /// a cast from `TypedUuid<PgConnKind>` to `TypedUuid<DbConnKind>`
320+ /// makes sense.
321+ /// * The inverse cast would not make sense, as a database connection may not
322+ /// necessarily be a Postgres connection.
323+ ///
324+ /// This interface provides an alternative, safer way to perform this
325+ /// conversion. Indicate your intention to allow a conversion between kinds
326+ /// by implementing `From<T> for U`, as shown in the example below.
327+ ///
328+ /// # Examples
329+ ///
330+ /// ```
331+ /// use newtype_uuid::{TypedUuid, TypedUuidKind, TypedUuidTag};
332+ ///
333+ /// // Let's say that these UUIDs represent repositories for different
334+ /// // version control systems, such that you have a generic RepoKind:
335+ /// pub enum RepoKind {}
336+ /// impl TypedUuidKind for RepoKind {
337+ /// fn tag() -> TypedUuidTag {
338+ /// const TAG: TypedUuidTag = TypedUuidTag::new("repo");
339+ /// TAG
340+ /// }
341+ /// }
342+ ///
343+ /// // You also have more specific kinds:
344+ /// pub enum GitRepoKind {}
345+ /// impl TypedUuidKind for GitRepoKind {
346+ /// fn tag() -> TypedUuidTag {
347+ /// const TAG: TypedUuidTag = TypedUuidTag::new("git_repo");
348+ /// TAG
349+ /// }
350+ /// }
351+ /// // (and HgRepoKind, JujutsuRepoKind, etc...)
352+ ///
353+ /// // First, define a `From` impl. This impl indicates your desire
354+ /// // to convert from one kind to another.
355+ /// impl From<GitRepoKind> for RepoKind {
356+ /// fn from(value: GitRepoKind) -> Self {
357+ /// match value {}
358+ /// }
359+ /// }
360+ ///
361+ /// // Now you can convert between them:
362+ /// let git_uuid: TypedUuid<GitRepoKind> =
363+ /// TypedUuid::from_u128(0xe9245204_34ea_4ca7_a1c6_2e94fa49df61);
364+ /// let repo_uuid: TypedUuid<RepoKind> = git_uuid.cast();
365+ /// ```
366+ #[ inline]
367+ #[ must_use]
368+ pub const fn cast < U : TypedUuidKind > ( self ) -> TypedUuid < U >
369+ where
370+ T : Into < U > ,
371+ {
372+ TypedUuid {
373+ uuid : self . uuid ,
374+ _phantom : PhantomData ,
375+ }
376+ }
301377}
302378
303379// ---
0 commit comments