From b06add7527b0f1bcbf8218b3ccdda061286b4523 Mon Sep 17 00:00:00 2001 From: Nikita Bishonen Date: Wed, 18 Mar 2026 21:12:39 +0000 Subject: [PATCH 1/2] (docs): redefine HasTimeType constraints --- content/associated-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/associated-types.md b/content/associated-types.md index 7cffbb1..522260b 100644 --- a/content/associated-types.md +++ b/content/associated-types.md @@ -329,7 +329,7 @@ Fortunately, CGP allows us to apply the same principle of impl-side dependencies # #[cgp_type] pub trait HasTimeType { - type Time: Eq + Ord; + type Time; } # # #[cgp_type] From 3004b3be3c3998ca1d7e2fa7e75d1885afbcd05e Mon Sep 17 00:00:00 2001 From: Nikita Bishonen Date: Wed, 18 Mar 2026 21:34:32 +0000 Subject: [PATCH 2/2] Comparison to Newtype Pattern deduplication --- content/associated-types.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/content/associated-types.md b/content/associated-types.md index 522260b..62789bb 100644 --- a/content/associated-types.md +++ b/content/associated-types.md @@ -503,16 +503,6 @@ The choice between abstract types, newtypes, or using both together isn't about Just keep in mind that abstract types are a core and widely used pattern in the CGP ecosystem, and you'll see them frequently demonstrated throughout this book. -## Comparison to Newtype Pattern - -Abstract types serve as an alternative to the newtype pattern. Compared to the newtype pattern, we can use plain `String` values directly, without wrapping them in a newtype struct. - -Contrary to common wisdom, in CGP, we place less emphasis on wrapping every domain type in a newtype. This is particularly true when most of the application is written in a context-generic style. The reason is simple: abstract types, when used within generic code, effectively provide the same level of encapsulation and type safety that newtypes offer. They protect the underlying raw values through their defined interfaces, often making the extra layer of newtype wrapping unnecessary boilerplate. - -The choice between abstract types, newtypes, or using both together isn't about a rigid "right" or "wrong." It's a flexible decision based on your specific project requirements, team conventions, and personal preference – choosing the best tool for the job at hand. - -Just keep in mind that abstract types are a core and widely used pattern in the CGP ecosystem, and you'll see them frequently demonstrated throughout this book. - ## The `UseType` Pattern Implementing type providers can quickly become repetitive as the number of abstract types grows. For example, to use `String` as the `AuthToken` type, we first need to define a new struct, `UseStringAuthToken`, and then implement `AuthTokenTypeProvider` for it. To streamline this process, the `cgp_type!` macro simplifies the implementation by automatically generating a provider using the _`UseType`_ pattern. The generated implementation looks like this: