Skip to content

Commit 4538b2c

Browse files
authored
Merge pull request #4 from contextgeneric/hypershell
Publish the release of v0.4.1 and Hypershell
2 parents a42463a + 6081cae commit 4538b2c

12 files changed

Lines changed: 1777 additions & 13 deletions

File tree

code/bin/hello.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub trait CanGreet // Name of the consumer trait
1010
// A getter trait representing a dependency for `name` value
1111
#[cgp_auto_getter] // Derive blanket implementation
1212
pub trait HasName {
13-
fn name(&self) -> &String;
13+
fn name(&self) -> &str;
1414
}
1515

1616
// Implement `Greeter` that is generic over `Context`

config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ build_search_index = true
1111
[markdown]
1212

1313
highlight_code = true
14-
highlight_theme = "kronuz"
14+
highlight_theme = "visual-studio-dark"
1515

1616
[extra]
1717

content/_index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ sort_by = "weight"
1010

1111
# Announcement
1212

13-
I'm excited to announce the release of [v0.4.0](https://github.com/contextgeneric/cgp/releases/tag/v0.4.0) of the [`cgp`](https://docs.rs/cgp/0.4.0/cgp/) crate. This update includes significantly improved developer experience, improved debuggability, and many more new features!
13+
I am thrilled to announce the release of `cgp` [v0.4.1](/blog/v0-4-1-release), along with the release of [**Hypershell**](/blog/hypershell-release), a modular, *type-level* domain-specific language (DSL) for writing shell-script-like programs in Rust.
1414

15-
Read the blog post for more details: [CGP v0.4.0 is Here: Unlocking Easier Debugging, Extensible Presets, and More!](/blog/v0-4-0-release/).
15+
Read the blog post for more details: [**Hypershell: A Type-Level DSL for Shell-Scripting in Rust**](/blog/hypershell-release).
1616

1717
# Overview
1818

content/blog/2025-06-14-hypershell-release.md

Lines changed: 1579 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
+++
2+
3+
title = "CGP v0.4.1 Release"
4+
5+
description = "Announcing the release of CGP v0.4.1, with new features like the cgp-handler crate, improved preset macros, and more."
6+
7+
authors = ["Soares Chen"]
8+
9+
+++
10+
11+
We are excited to announce the release of CGP v0.4.1! This release brings several new features, quality-of-life improvements for macro usages, and a new crate `cgp-handler`.
12+
13+
Here are some of the highlights:
14+
15+
- **New `cgp-handler` crate**: Provides abstract interfaces for defining components with common method signatures.
16+
- **`cgp_preset!` macro improvement**: Now supports wrapping of `Preset::Provider`.
17+
- **`#[cgp_component]` macro improvement**: Now supports automated derivation of `UseDelegate`.
18+
- **Improved Documentation**: Added inline Rust documentation for common CGP constructs.
19+
20+
Below we will go through some of the most significant changes in this release.
21+
22+
# New `cgp-handler` Crate
23+
24+
This release introduces a new `cgp-handler` crate, which offers abstract interfaces for defining components with common method signatures. This helps in creating reusable and composable handlers for various tasks.
25+
26+
As a semi-stable and non-essential crate, the `cgp-handler` crate is re-exported by `cgp-extra`, and is available from `cgp::extra::handler`.
27+
28+
The introduction of `cgp-handler` is mainly to support the development of [Hypershell](/blog/hypershell-release), which makes heavy use of the `Handler` component to design and implement its DSL providers.
29+
30+
The crate introduces three main components: `Handler`, `Computer`, and `Producer`.
31+
32+
## `Handler`
33+
34+
The `Handler` component provides the most commonly used interface for performing asynchronous operations that may fail:
35+
36+
```rust
37+
#[cgp_component(Handler)]
38+
#[async_trait]
39+
pub trait CanHandle<Code: Send, Input: Send>: HasAsyncErrorType {
40+
type Output: Send;
41+
42+
async fn handle(
43+
&self,
44+
_tag: PhantomData<Code>,
45+
input: Input,
46+
) -> Result<Self::Output, Self::Error>;
47+
}
48+
```
49+
50+
## `Computer`
51+
52+
The `Computer` component mirrors a pure function that takes some input, performs some computation, and produces an output.
53+
54+
```rust
55+
#[cgp_component(Computer)]
56+
pub trait CanCompute<Code, Input> {
57+
type Output;
58+
59+
fn compute(&self, _tag: PhantomData<Code>, input: Input) -> Self::Output;
60+
}
61+
```
62+
63+
## `Producer`
64+
65+
The `Producer` component mirrors a global singleton function to produce an output value. It is useful to emulate global values that cannot be constructed through the `const` context in Rust, such as `String`.
66+
67+
```rust
68+
#[cgp_component(Producer)]
69+
pub trait CanProduce<Code> {
70+
type Output;
71+
72+
fn produce(&self, _tag: PhantomData<Code>) -> Self::Output;
73+
}
74+
```
75+
76+
## `Code` Parameter
77+
78+
All the traits in `cgp-handler` contain a phantom `Code` parameter that can be used for building type-level DSLs such as [Hypershell](https://github.com/contextgeneric/hypershell). They can also be used as type-level identifiers for dispatching, such as in API handlers.
79+
80+
# `cgp_preset!` Macro Improvements
81+
82+
This release also brings minor improvements to our `cgp_preset!` macro, supporting the definition of CGP presets for more diverse use cases.
83+
84+
## Support for Wrapping `Preset::Provider` in `cgp_preset!`
85+
86+
The `cgp_preset!` macro now allows users to specify a `#[wrap_provider]` attribute to wrap the `Preset::Provider` type. This is particularly useful when using CGP presets to define extensible mappings for generic dispatch through the `UseDelegate` pattern.
87+
88+
Wrapping the provider makes it easier to extend non-provider mappings across multiple levels of preset inheritance. The wrapped `Preset::Provider` type will implement the expected provider trait, making it a valid delegation target.
89+
90+
### Example
91+
92+
Given the following preset definition:
93+
94+
```rust
95+
cgp_preset! {
96+
#[wrap_provider(UseDelegate)]
97+
MyHandlerPreset {
98+
String: HandleString,
99+
u64: HandleU64,
100+
...
101+
}
102+
}
103+
```
104+
105+
The macro generates the following implementation:
106+
107+
```rust
108+
pub mod MyHandlerPreset {
109+
...
110+
111+
pub type Provider = UseDelegate<Components>;
112+
113+
delegate_components! {
114+
new Components {
115+
String: HandleString,
116+
u64: HandleU64,
117+
...
118+
}
119+
}
120+
121+
...
122+
}
123+
```
124+
125+
## Automated `UseDelegate` Derivation in `#[cgp_component]`
126+
127+
The `#[cgp_component]` family of macros now includes a `derive_delegate` field, which allows for the automated implementation of `UseDelegate` for CGP components. This reduces boilerplate code that was previously required to be implemented manually.
128+
129+
### Example
130+
131+
The updated `ErrorRaiser` component can now be defined as:
132+
133+
```rust
134+
#[cgp_component {
135+
provider: ErrorRaiser,
136+
derive_delegate: UseDelegate<SourceError>,
137+
}]
138+
pub trait CanRaiseError<SourceError>: HasErrorType {
139+
fn raise_error(error: SourceError) -> Self::Error;
140+
}
141+
```
142+
143+
This will automatically derive the `UseDelegate` implementation:
144+
145+
```rust
146+
#[cgp_provider(ErrorRaiserComponent)]
147+
impl<Context, SourceError, Components, Delegate> ErrorRaiser<Context, SourceError>
148+
for UseDelegate<Components>
149+
where
150+
Context: HasErrorType,
151+
Components: DelegateComponent<SourceError, Delegate = Delegate>,
152+
Delegate: ErrorRaiser<Context, SourceError>,
153+
{
154+
fn raise_error(e: SourceError) -> Context::Error {
155+
Delegate::raise_error(e)
156+
}
157+
}
158+
```
159+
160+
# Other Improvements
161+
162+
This release also includes several other minor improvements and fixes:
163+
164+
- **Improved Documentation**: We have added inline Rust documentation for many common CGP constructs, making it easier for developers to understand and use them. This is part of our ongoing effort to improve the developer experience.
165+
- **Static `Char` Formatting**: The `Char` type can now be formatted statically without requiring `self`, which allows type-level strings to be formatted without constructing any value.
166+
- Use `__Self__` instead of `T` when deriving `Preset::IsPreset` to avoid identifier conflicts when users use `T` in their generic parameters.
167+
- Included trait bound identifiers in `Preset::components` re-export.
168+
169+
---
170+
171+
We hope you enjoy the new features and improvements in this release. As always, we welcome feedback and contributions from the community. Check out the project on [GitHub](https://github.com/contextgeneric/cgp/) and the full [changelog](https://github.com/contextgeneric/cgp/blob/main/CHANGELOG.md) for more details.

content/contribute.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ Help raise awareness of CGP by sharing it on social media. Follow our official B
3434

3535
## Write About It
3636

37-
If you find CGP interesting, consider writing your own blog posts or tutorials to share your learning journey. Sharing your insights can help others learn CGP in different ways, and even if the topic is already covered on the official site, your perspective might make it clearer to others.
37+
If you find CGP interesting, consider writing your own blog posts or tutorials to share your learning journey. Sharing your insights can help others learn CGP in different ways, and even if the topic is
38+
already covered on the official site, your perspective might make it clearer to others.
39+
40+
## Sponsor Me
41+
42+
If you appreciate my work and want to see CGP gain wider adoption, the best way to support it is to *sponsor* me, regardless of the amount. I have sponsorship pages on [Github Sponsor](https://github.com/sponsors/soareschen/), [Patreon](www.patreon.com/c/maybevoid/about), and [Ko-Fi](https://ko-fi.com/maybevoid).
43+
44+
*As with most open-source projects*, I don't expect sponsorship to be enough to allow me to quit my job and work full-time on CGP, or even *with* CGP. *However*, any financial support will significantly boost my confidence in the *value* of my work and encourage me to continue dedicating hundreds of hours of my free time to it instead of other pursuits.
45+
46+
I do hope to eventually spend a year or two working full-time on CGP using my *personal savings*, even if sponsorships don't cover my living expenses. *However*, exponential growth is important, and if I could secure around a quarter of my living expenses through monthly sponsorship, it would reduce some risk and suggest a higher chance of CGP becoming self-sustaining later on.
3847

3948
# Acknowledgement
4049

static/blog/images/cgp-wiring.png

68.8 KB
Loading
143 KB
Loading
243 KB
Loading
60.8 KB
Loading

0 commit comments

Comments
 (0)