hey_chat_gpt 1.2.1

A proc-macro to delegate implementation to the ChatGPT API. ChatGPT APIに実装を代行してもらうマクロです。
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
//! # A proc-macro to delegate implementation to the ChatGPT API.
//!
//! ChatGPT APIに実装を代行してもらうマクロです。
//!
//! **This crate requires `nightly` toolchain!**
//!
//! 本クレートでは `nightly` ツールチェイン必須です!
//!
//! - [`take_care_of_the_rest`](crate::take_care_of_the_rest!)
//! - [`あとは任せた`](crate::あとは任せた!)
//!
//! ```rust
//! use hey_chat_gpt::take_care_of_the_rest;
//!
//! fn main() {
//!     println!("{}", fib(10));
//! }
//!
//! take_care_of_the_rest!();
//! # fn fib(n: usize) -> usize {
//! #     match n {
//! #         m @ 0..=1 => m,
//! #         m => fib(m - 2) + fib(m - 1)
//! #     }
//! # }
//! ```
//!
//! The difference between the two macros is whether they are in English or Japanese.
//!
//! この2つのマクロの違いは、英語か日本語かです。
//!
//! Please see the links for each macro for more details.
//!
//! 詳細は各マクロのリンク先で読んでください。
//!
//! ## Preparation
//!
//! To compile, run the below command.
//!
//! ```bash
//! OPENAI_API_KEY=sk-YOUR-API-KEY RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo +nightly run
//! ```
//!
//! - `OPENAI_API_KEY`: api key.
//! - `RUSTFLAGS=...`: to enable [`source_file` method](https://doc.rust-lang.org/proc_macro/struct.Span.html#method.source_file) of [Span](https://doc.rust-lang.org/proc_macro/struct.Span.html).
//! - `cargo +nightly run`: the reason of specify `nightly` is same as above.
//!
//! These settings can also be enable by setting files.
//!
//! `.cargo/config.toml`
//!
//! ```toml:.cargo/config.toml
//! [build]
//! rustflags = ["--cfg=procmacro2_semver_exempt"]
//!
//! [env]
//! OPENAI_API_KEY = "sk-YOUR-API-KEY"
//! ```
//!
//! `rust-toolchain.toml`
//!
//! ```toml:rust-toolchain.toml
//! [toolchain]
//! channel = "nightly"
//! ```
//!
//! In this case, the options are not necessary.
//!
//! ```bash
//! cargo run
//! ```
//!
//! ## Cache
//!
//! Responses from ChatGPT are stored in the gpt_responses directory and used as a cache when the code remains unchanged. If you get undesirable code or an error response from ChatGPT, remove those cache files before trying to compile again.
//!
//! ## 使用のための準備
//!
//! コンパイルするには以下を実行します。
//!
//! ```bash
//! OPENAI_API_KEY=sk-YOUR-API-KEY RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo +nightly run
//! ```
//!
//! - `OPENAI_API_KEY`: 取得してきたOpenAIのAPIキーを設定してください。
//! - `RUSTFLAGS=...`: [Span](https://doc.rust-lang.org/proc_macro/struct.Span.html) の [`source_file`](https://doc.rust-lang.org/proc_macro/struct.Span.html#method.source_file) メソッドを使用するために指定しています。
//! - `cargo +nightly run`: `nightly` の指定理由は上記と同じです。
//!
//! 設定ファイルを通しての設定も可能です。
//!
//! `.cargo/config.toml`
//!
//! ```toml:.cargo/config.toml
//! [build]
//! rustflags = ["--cfg=procmacro2_semver_exempt"]
//!
//! [env]
//! OPENAI_API_KEY = "sk-YOUR-API-KEY"
//! ```
//!
//! `rust-toolchain.toml`
//!
//! ```toml:rust-toolchain.toml
//! [toolchain]
//! channel = "nightly"
//! ```
//!
//! この場合オプションは不要になります。
//!
//! ```bash
//! cargo run
//! ```
//!
//! ## キャッシュファイルについて
//!
//! ChatGPTからの返答は `gpt_responses` ディレクトリに保存され、コードが変わらないうちはこちらのキャッシュがコンパイルに利用されます。もし望まない結果になったりエラーレスポンスが帰ってきた場合は、キャッシュファイルを削除の上再コンパイルしてみてください。

mod impls;

use proc_macro::TokenStream;
use syn::Error;

fn english_message(macro_name: &str) -> String {
    format!(
        r#"I'm the administrator of this system. You are an AI assistant of this system helping with Rust programming, and you are called through `{macro_name}` proc-macro. Generate Rust code based on the user's input as proc-macro (`{macro_name}` macro) output. Ensure the code is idiomatic, adheres to Rust best practices, and includes comments for clarity. All your answers will be treated as `String` values and converted to `proc_macro2::TokenStream` , so your answers must be valid Rust code. **Anything that is not Rust code must be in a comment, and you must not output anything that would prevent the conversion. And User input other than macros remains, so be careful not to create duplicates. (For example, if you output a main function, it may conflict with a user-defined main function and cause a compilation error. Or `{macro_name}` macro may be called from within the main function, in which case you should not print the main function itself.)**. What follows is inputs of the user who uses this system:

"#
    )
}

fn japanese_message(macro_name: &str) -> String {
    format!(
        r#"私はこのシステムの管理者です。あなたはRustプログラミングを支援する本システムのAIアシスタントであり、`{macro_name}` 手続きマクロを通じて呼び出されます。ユーザーの入力に基づいてRustコードを `{macro_name}` マクロの出力として生成してほしいです。コードはRustのベストプラクティスに従い、明確さを保つための日本語のコメントを含めるようにしてください。回答はすべて `String` 値として扱われ、`proc_macro2::TokenStream` に変換されるため、回答は有効なRustコードである必要があります。**Rustコード以外のものはすべてコメント内に記述する必要があり、Rustコードとして変換しようとするとエラーになるものを出力してはなりません。そして、マクロ以外のユーザー入力はそのまま残るため、重複などをしないように注意してください。(たとえば、 `main` 関数を出力すると、ユーザー定義の `main` 関数と競合してコンパイルエラーが発生する可能性があります。あるいは、 `{macro_name}` マクロはmain関数の中からよばれているかもしれません。その時にmain関数ごと出力してはいけません。)** ここからは本システム利用者の入力になります:

"#
    )
}

/// A macro to delegate implementation to the ChatGPT API.
///
/// **This crate requires `nightly` toolchain!**
///
/// This macro sends the entire file containing it to the [OpenAI API](https://platform.openai.com/),
/// and replaces it with the result returned by the API.
///
/// # Example
///
/// ```rust
/// use hey_chat_gpt::take_care_of_the_rest;
///
/// fn main() {
///     println!("{}", fib(10));
/// }
///
/// take_care_of_the_rest!();
/// # fn fib(n: usize) -> usize {
/// #     match n {
/// #         m @ 0..=1 => m,
/// #         m => fib(m - 2) + fib(m - 1)
/// #     }
/// # }
/// ```
///
/// # Options
///
/// You can pass several options in the form of `key = value`.
/// Additionally, although it's not strictly necessary to mention here,
/// you can pass string literals as well, which can be used to provide a prompt.
///
/// | key                   | Type   | Default         | Possible Values               | Description |
/// |:----------------------|:-------|:----------------|:-------------------------------|:------------|
/// | model                 | String | "gpt-4o"        | "o1-preview", etc.             | Specifies the GPT model to use. |
/// | seed                  | Integer| File hash       | Integer value ≤ 9223372036854775807 | Provides a seed for reproducibility. Try this if the default results are unsatisfactory. |
/// | max_completion_tokens | Integer| None            | | Sets the maximum number of tokens for the response. Might help when the output is truncated (unverified). |
///
/// Example with options:
///
/// ```rust
/// fn main() {
///     println!("{}", fib(10));
/// }
///
/// hey_chat_gpt::take_care_of_the_rest!(
///     model = "o1-preview";
///     seed = 20;
///     max_completion_tokens = 4096;
///     "Implement a function that generates a Fibonacci sequence (a_{n-1} + a_{n} = a_{n+1}) starting with 1, 1."
/// );
/// # fn fib(n: usize) -> usize {
/// #     match n {
/// #         m @ 0..=1 => m,
/// #         m => fib(m - 2) + fib(m - 1)
/// #     }
/// # }
/// ```
///
/// # Preparation
///
/// To compile, run the below command.
///
/// ```bash
/// OPENAI_API_KEY=sk-YOUR-API-KEY RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo +nightly run
/// ```
///
/// - `OPENAI_API_KEY`: api key.
/// - `RUSTFLAGS=...`: to enable [`source_file` method](https://doc.rust-lang.org/proc_macro/struct.Span.html#method.source_file) of [Span](https://doc.rust-lang.org/proc_macro/struct.Span.html).
/// - `cargo +nightly run`: the reason of specify `nightly` is same as above.
///
/// These settings can also be enable by setting files.
///
/// `.cargo/config.toml`
///
/// ```toml:.cargo/config.toml
/// [build]
/// rustflags = ["--cfg=procmacro2_semver_exempt"]
///
/// [env]
/// OPENAI_API_KEY = "sk-YOUR-API-KEY"
/// ```
///
/// `rust-toolchain.toml`
///
/// ```toml:rust-toolchain.toml
/// [toolchain]
/// channel = "nightly"
/// ```
///
/// In this case, the options are not necessary.
///
/// ```bash
/// cargo run
/// ```
///
/// ## Cache
///
/// Responses from ChatGPT are stored in the gpt_responses directory and used as a cache when the code remains unchanged. If you get undesirable code or an error response from ChatGPT, remove those cache files before trying to compile again.
#[proc_macro]
pub fn take_care_of_the_rest(input: TokenStream) -> TokenStream {
    let input = syn::parse_macro_input!(input as impls::MacroInput);

    impls::take_care_of_the_rest(input, &english_message("take_care_of_the_rest"))
        .unwrap_or_else(Error::into_compile_error)
        .into()
}

/// ChatGPT APIに実装を代行してもらうマクロです。
///
/// **本クレートでは `nightly` ツールチェイン必須です!**
///
/// このマクロを記述したファイル全体を[OpenAI API](https://platform.openai.com/)に投げ、返ってきた結果で置換します。
///
/// # Example
///
/// ```rust
/// use hey_chat_gpt::あとは任せた;
///
/// fn main() {
///     println!("{}", fib(10));
/// }
///
/// あとは任せた!();
/// # fn fib(n: usize) -> usize {
/// #     match n {
/// #         m @ 0..=1 => m,
/// #         m => fib(m - 2) + fib(m - 1)
/// #     }
/// # }
/// ```
///
/// # Option
///
/// `key = value` 形式でいくつかのオプションを渡すことができます。また、(ここに記述する必要性はないですが)文字列リテラルも受け取れるのでここにプロンプトを記述することもできます。
///
/// | key                   | 型     | デフォルト       | 候補                            | 説明 |
/// |:----------------------|:------ |:---------------|:-------------------------------|:-----|
/// | model                 | 文字列  | "gpt-4o"       | "o1-preview" 等                | 使用するGPTのモデルを指定します。 |
/// | seed                  | 整数値 | ファイルハッシュ   | 9223372036854775807 以下の整数値 | 再現性確保のために与えるシード値を与えます。デフォルトだと芳しくない結果になった時に指定してみてください。 |
/// | max_completion_tokens | 整数値 | 指定なし          | | 返答の最大トークン数を設定します。生成が中途半端になった時に使えるかも...?(未検証) |
///
/// オプションを指定した場合の例
///
/// ```rust
/// fn main() {
///     println!("{}", fib(10));
/// }
///
/// hey_chat_gpt::あとは任せた!(
///     model = "o1-preview";
///     seed = 20;
///     max_completion_tokens = 4096;
///     "1, 1で始まるフィボナッチ数列(a_{n-1} + a_{n} = a_{n+1})を生成する関数を実装してください。"
/// );
/// # fn fib(n: usize) -> usize {
/// #     match n {
/// #         m @ 0..=1 => m,
/// #         m => fib(m - 2) + fib(m - 1)
/// #     }
/// # }
/// ```
///
/// # 使用のための準備
///
/// コンパイルするには以下を実行します。
///
/// ```bash
/// OPENAI_API_KEY=sk-YOUR-API-KEY RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo +nightly run
/// ```
///
/// - `OPENAI_API_KEY`: 取得してきたOpenAIのAPIキーを設定してください。
/// - `RUSTFLAGS=...`: [Span](https://doc.rust-lang.org/proc_macro/struct.Span.html) の [`source_file`](https://doc.rust-lang.org/proc_macro/struct.Span.html#method.source_file) メソッドを使用するために指定しています。
/// - `cargo +nightly run`: `nightly` の指定理由は上記と同じです。
///
/// 設定ファイルを通しての設定も可能です。
///
/// `.cargo/config.toml`
///
/// ```toml:.cargo/config.toml
/// [build]
/// rustflags = ["--cfg=procmacro2_semver_exempt"]
///
/// [env]
/// OPENAI_API_KEY = "sk-YOUR-API-KEY"
/// ```
///
/// `rust-toolchain.toml`
///
/// ```toml:rust-toolchain.toml
/// [toolchain]
/// channel = "nightly"
/// ```
///
/// この場合オプションは不要になります。
///
/// ```bash
/// cargo run
/// ```
///
/// ## キャッシュファイルについて
///
/// ChatGPTからの返答は `gpt_responses` ディレクトリに保存され、コードが変わらないうちはこちらのキャッシュがコンパイルに利用されます。もし望まない結果になったりエラーレスポンスが帰ってきた場合は、キャッシュファイルを削除の上再コンパイルしてみてください。
#[proc_macro]
pub fn あとは任せた(input: TokenStream) -> TokenStream {
    let input = syn::parse_macro_input!(input as impls::MacroInput);

    impls::take_care_of_the_rest(input, &japanese_message("あとは任せた"))
        .unwrap_or_else(Error::into_compile_error)
        .into()
}

// Define aliases for other phrases.
macro_rules! define_macro_aliases {
    ($doc_comment:literal, $message_fn:ident, [$($alias:ident),* $(,)?]) => {
        $(
            #[doc = $doc_comment]
            #[proc_macro]
            pub fn $alias(input: TokenStream) -> TokenStream {
                let input = syn::parse_macro_input!(input as impls::MacroInput);

                impls::take_care_of_the_rest(input, &$message_fn(stringify!($alias)))
                    .unwrap_or_else(Error::into_compile_error)
                    .into()
            }
        )*
    };
}
// English aliases
define_macro_aliases!(
    " An alias for [`take_care_of_the_rest`](crate::take_care_of_the_rest!).",
    english_message,
    [
        do_it,
        go_ahead,
        try_it,
        just_do_it,
        give_it_a_go,
        help_me,
        lend_a_hand,
        back_me_up,
        save_me,
        magic,
        abracadabra,
        wave_your_wand,
        perform_miracle,
        finish_it,
        wrap_it_up,
        get_it_done,
        make_it_happen,
        deliver_it,
    ]
);
// Japanese aliases
define_macro_aliases!(
    " [`あとは任せた`](crate::あとは任せた!) へのエイリアス。",
    japanese_message,
    [
        やって,
        これやって,
        進めて,
        頼む,
        手を貸して,
        助けて,
        手伝って,
        魔法を見せて,
        奇跡を起こして,
        何とかして,
        仕上げて,
        完成させて,
        終わらせて,
        最後まで頼む,
        実現して,
        作って,
        やり遂げて,
    ]
);