You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/_index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ sort_by = "weight"
10
10
11
11
# Announcement
12
12
13
-
I am excited to announce the release of [**cgp-serde**](/blog/cgp-serde-release/), a modular serialization library for Serde that leverages the power of [**Context-Generic Programming**](/).
13
+
I am excited to announce the release of [**cgp-serde**](/blog/cgp-serde-release/), a modular serialization library for Serde that leverages the power of **Context-Generic Programming**.
14
14
15
15
[Read the announcement blog post](/blog/cgp-serde-release/) to find out more.
16
16
@@ -22,7 +22,7 @@ Context-Generic Programming (CGP) is a modular programming paradigm that enables
22
22
23
23
You can adapt almost any existing Rust trait to use CGP today by applying the `#[cgp_component]` macro to the trait definition. After this annotation, you can write **named** implementations of the trait using `#[cgp_impl]`, which can be defined without being constrained by the coherence rules. You can then selectively enable and reuse the named implementation for your type using the `delegate_components!` macro.
24
24
25
-
For instance, we can, in principle, annotate the standard library’s [`Hash`]([https://doc.rust-lang.org/std/hash/trait.Hash.html]\(https://doc.rust-lang.org/std/hash/trait.Hash.html\)) trait with `#[cgp_component]` like this:
25
+
For instance, we can, in principle, annotate the standard library’s [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html) trait with `#[cgp_component]` like this:
26
26
27
27
```rust
28
28
#[cgp_component(HashProvider)]
@@ -69,7 +69,7 @@ Even though the CGP project is officially still less than one year old, some of
69
69
70
70
## Blog Posts
71
71
72
-
The most accurate and up-to-date resources concerning CGP are currently available in the form of our insightful [blog posts](/blog). Specifically, we recommend that the blog posts starting from the [**v0.6.0 release onward**](/blog/v0-6-0-release/) will give you a significantly more concise and modern explanation of precisely what CGP is all about.
72
+
The most accurate and up-to-date resources concerning CGP are currently available in the form of our [blog posts](/blog). Specifically, we recommend that the blog posts starting from the [**v0.6.0 release onward**](/blog/v0-6-0-release/) will give you a significantly more concise and modern explanation of what CGP is all about.
Copy file name to clipboardExpand all lines: content/blog/2025-11-03-cgp-serde-release.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ For those readers new to the project, here is a quick introduction: Context-Gene
24
24
25
25
You can adapt almost any existing Rust trait to use CGP today by applying the `#[cgp_component]` macro to the trait definition. After this annotation, you can write **named** implementations of the trait using `#[cgp_impl]`, which can be defined without being constrained by the coherence rules. You can then selectively enable and reuse the named implementation for your type using the `delegate_components!` macro.
26
26
27
-
For instance, we can, in principle, annotate the standard library’s [`Hash`]([https://doc.rust-lang.org/std/hash/trait.Hash.html]\(https://doc.rust-lang.org/std/hash/trait.Hash.html\)) trait with `#[cgp_component]` like this:
27
+
For instance, we can, in principle, annotate the standard library’s [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html) trait with `#[cgp_component]` like this:
Compared to the original `Serialize` trait, `cgp-serde` provides the `CanSerializeValue` CGP trait, which moves the original `Self` type from `Serialize` to an explicit generic parameter named`Value`. The `Self` type in `CanSerializeValue` now represents a **context** type, which can be used for **dependency injection**. The `serialize` method also accepts an extra `&self` value, making it possible to retrieve additional runtime dependencies from this context.
76
+
Compared to the original `Serialize` trait, `cgp-serde` provides the `CanSerializeValue` CGP trait, which moves the original `Self` type from `Serialize` to an explicit generic parameter called`Value`. The `Self` type in `CanSerializeValue` now represents a **context** type, which can be used for **dependency injection**. The `serialize` method also accepts an extra `&self` value, making it possible to retrieve additional runtime dependencies from this context.
77
77
78
78
In a similar manner, `cgp-serde` defines a context-generic version of the [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) trait as follows:
Copy file name to clipboardExpand all lines: content/tutorials/hello.md
+9-11Lines changed: 9 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,17 +19,15 @@ pub trait CanGreet {
19
19
}
20
20
```
21
21
22
-
The `cgp` crate provides common constructs through its `prelude` module, which should be imported in most cases. The first CGP construct we use here is the `#[cgp_component]` macro. This macro generates additional CGP constructs for the greeter component.
22
+
The `cgp` crate provides common constructs through its `prelude` module, which should be imported in most cases. The first CGP construct we use here is the `#[cgp_component]` macro. This macro generates additional CGP constructs for the `Greeter` trait.
23
23
24
-
The target of this macro, `CanGreet`, is a **consumer trait** used similarly to regular Rust traits. However, unlike traditional traits, we won't implement anything directly on this trait.
24
+
The target of this macro, `CanGreet`, is a **consumer trait** used similarly to regular Rust traits. However, unlike traditional traits, we won't usually implement anything directly on this trait. The argument to the macro, `Greeter`, designates a **provider trait** for the component. The `Greeter` trait is used to define the actual implementations for the greeter component. It has a similar structure to `CanGreet`, but with the implicit `Self` type replaced by a generic `Context` type.
25
25
26
-
In its simplified form, the argument to the macro, `Greeter`, designates a **provider trait** for the component. The `Greeter` provider is used to define the actual implementations for the greeter component. It has a similar structure to `CanGreet`, but with the implicit `Self` type replaced by a generic `Context` type.
27
-
28
-
The macro also generates an empty `GreeterComponent` struct, which is used as the _name_ of the greeter component which can be used for the component wiring later on.
26
+
The macro also generates an empty `GreeterComponent` struct, which is used as the **name** of the greeter component which can be used for the component wiring later on.
29
27
30
28
## Name Getter
31
29
32
-
Now, we will define an _getter trait_ to retrieve the name value from a context:
30
+
Now, we will define an **auto getter trait** to retrieve the name value from a context:
33
31
34
32
```rust
35
33
#[cgp_auto_getter]
@@ -40,7 +38,7 @@ pub trait HasName {
40
38
41
39
The `HasName` trait contains the getter method `name`, which returns a `&str` string value.
42
40
43
-
The `#[cgp_auto_getter]` attribute macro applied to `HasName` automatically generates a blanket implementation. This enables any context containing a field named `name` of type `String` to automatically implement the `HasName` trait.
41
+
The `#[cgp_auto_getter]` attribute macro applied to `HasName` automatically generates a blanket implementation. This enables any context containing a field named `name` of type `String` to automatically implement the `HasName` trait, if it also derives the `HasField` trait.
44
42
45
43
## Hello Greeter
46
44
@@ -60,11 +58,11 @@ where
60
58
61
59
We use `#[cgp_impl]` to define a new provider, called `GreetHello`, which implements the `Greeter` provider trait. The implementation is written to be **generic** over any `Context` type that implements `HasName`.
62
60
63
-
Normally, it would not be possible to write a blanket implementation like this in vanilla Rust, due to it violating the *overlapping* and *orphan* rules of Rust traits. However, the use of `#[cgp_impl]` and the `Greeter` provider trait allows us to **bypass** this restriction.
61
+
Normally, it would not be possible to write a blanket implementation like this in vanilla Rust, due to it violating the **overlapping** and **orphan** rules of Rust traits. However, the use of `#[cgp_impl]` and the `Greeter` provider trait allows us to **bypass** this restriction.
64
62
65
-
Behind the scene, the macro generates an empty struct named `GreetHello`, which is used as an *identifier* of the provider that implements the `Greeter` trait.
63
+
Behind the scene, the macro generates an empty struct named `GreetHello`, which is used as an **identifier** of the provider that implements the `Greeter` trait.
66
64
67
-
Notice that the constraint `HasName` is specified only in the `impl` block, not in the trait bounds for `CanGreet` or `Greeter`. This design allows us to use _dependency injection_ for both values and _types_ through Rust’s trait system.
65
+
Notice that the constraint `HasName` is specified only in the `impl` block, *not* in the trait bounds for `CanGreet` or `Greeter`. This design allows us to use **dependency injection** through Rust’s trait system.
68
66
69
67
## Person Context
70
68
@@ -79,7 +77,7 @@ pub struct Person {
79
77
80
78
The `Person` context is defined as a struct containing a `name` field of type `String`.
81
79
82
-
We use the `#[derive(HasField)]` macro to automatically derive `HasField` implementations for every field in `Person`. This works together with the blanket implementation generated by `#[cgp_auto_getter]` for `HasName`, allowing `HasName` to be automatically implemented for `Person` without requiring any additional code.
80
+
We use the `#[derive(HasField)]` macro to automatically derive `HasField` implementations for every field in `Person`. This works together with the blanket implementation generated by `#[cgp_auto_getter]` for `HasName`, allowing `HasName` to be **automatically implemented** for `Person` without requiring any additional code.
0 commit comments