15 промтов для Rust: системное программирование, CLI и WebAssembly

Введение

Rust — это язык системного программирования, который сочетает производительность C++ с безопасностью памяти, предотвращая целые классы уязвимостей. Согласно отчёту Stack Overflow Developer Survey 2025, Rust уже восьмой год подряд занимает первое место среди «самых любимых» языков программирования. Его экосистема активно растёт: от CLI-утилит (ripgrep, fd, bat) до WebAssembly-фреймворков (Yew, Dioxus, Leptos).

Однако даже опытные разработчики тратят до 40% времени на рутинные задачи: написание безопасного unsafe-кода, парсинг конфигураций, генерацию бойлерплейта для WASM. Современные языковые модели, такие как GPT-4o и Claude 3.5 Sonnet, способны ускорить эти процессы, если правильно формулировать запросы.

В этой подборке — 15 конкретных промтов, которые помогут вам:
- Писать безопасный и идиоматичный код на Rust
- Создавать CLI-утилиты с нуля
- Работать с WebAssembly (WASM) и парсить данные

Каждый промт готов к копированию. Указывайте свою версию Rust (проверьте через rustc --version) — примеры рассчитаны на стабильный релиз 1.85+ (июль 2026).


1. Генерация безопасного кода с нулевой стоимостью абстракций

Для чего: Создать идиоматичный Rust-код с использованием трейтов, дженериков и владения без утечек.

Промт:

Ты — эксперт по Rust с 10-летним опытом. Напиши функцию на Rust, которая:
- принимает замыкание и список чисел
- применяет замыкание к каждому элементу, возвращая новый вектор
- использует нулевые абстракции (zero-cost abstractions)
- включает аннотации lifetimes, если необходимо
- не использует unsafe код
Добавь комментарии с объяснением каждого шага. Версия Rust: 1.85.

Пример использования:

fn map_with_closure<T, F>(data: &[T], mut f: F) -> Vec<T>
where
    T: Clone,
    F: FnMut(&T) -> T,
{
data.iter().map(

|x| f(x)).collect()
}

fn main() {
    let numbers = vec![1, 2, 3];
let doubled = map_with_closure(&numbers,

|x| x * 2);
    println!("{:?}", doubled); // [2, 4, 6]
}

Почему это работает: Промт задаёт конкретные требования (lifetimes, zero-cost), что заставляет модель генерировать код с явными аннотациями и избегать клонирования без необходимости. Результат можно сразу вставить в main.rs.


2. Рефакторинг unsafe-кода в безопасный

Для чего: Преобразовать существующий код с unsafe в безопасный аналог с использованием std::cell, RefCell или Mutex.

Промт:

У меня есть код на Rust, который использует unsafe для модификации статической переменной:

static mut COUNTER: u32 = 0;

unsafe {
    COUNTER += 1;
}

Перепиши его без unsafe, используя std::sync::atomic или std::cell::Cell. Объясни, почему твой вариант безопаснее. Версия Rust: 1.85.

Пример использования:

use std::sync::atomic::{AtomicU32, Ordering};

static COUNTER: AtomicU32 = AtomicU32::new(0);

fn increment() {
    COUNTER.fetch_add(1, Ordering::SeqCst);
}

fn main() {
    increment();
    println!("{}", COUNTER.load(Ordering::SeqCst)); // 1
}

Почему это работает: Промт явно указывает проблему (unsafe для статической переменной) и просит альтернативу. Модель предлагает AtomicU32 — правильный выбор для многопоточности, что предотвращает data races.


3. Создание CLI-утилиты с clap и anyhow

Для чего: Быстро сгенерировать скелет CLI-приложения с парсингом аргументов и обработкой ошибок.

Промт:

Напиши полный код CLI-утилиты на Rust, которая:
- использует крейты clap 4.x и anyhow
- принимает флаг --verbose (bool) и аргумент --input (строка)
- читает файл по указанному пути и выводит количество строк
- обрабатывает ошибки (файл не найден, нет прав) с помощью anyhow
- имеет версию и описание
Выведи только код. Версия Rust: 1.85.

Пример использования:

use clap::Parser;
use anyhow::{Context, Result};
use std::fs;

#[derive(Parser)]
#[command(name = "line-counter")]
#[command(about = "Count lines in a file", long_about = None)]
struct Cli {
    #[arg(short, long, default_value_t = false)]
    verbose: bool,

    #[arg(short, long)]
    input: String,
}

fn main() -> Result<()> {
    let cli = Cli::parse();
    let content = fs::read_to_string(&cli.input)
        .with_context(|| format!("Failed to read file: {}", cli.input))?;
    let line_count = content.lines().count();
    if cli.verbose {
        println!("File: {}, Lines: {}", cli.input, line_count);
    } else {
        println!("{}", line_count);
    }
    Ok(())
}

Почему это работает: Промт использует популярные крейты (clap — де-факто стандарт для CLI, anyhow — для простой обработки ошибок). Код готов к запуску после добавления зависимостей в Cargo.toml.


4. Парсинг CSV с serde

Для чего: Прочитать CSV-файл с заголовками и десериализовать его в структуры.

Промт:

Напиши Rust-программу, которая:
- использует крейты csv 1.x и serde (Serialize, Deserialize)
- определяет структуру с полями: name (String), age (u32), email (String)
- читает CSV-файл "data.csv" с заголовками
- выводит всех пользователей старше 18 лет
- обрабатывает ошибки через anyhow
Выведи только код. Версия Rust: 1.85.

Пример использования:

use serde::Deserialize;
use anyhow::Result;

#[derive(Debug, Deserialize)]
struct User {
    name: String,
    age: u32,
    email: String,
}

fn main() -> Result<()> {
    let mut rdr = csv::Reader::from_path("data.csv")?;
    for result in rdr.deserialize() {
        let user: User = result?;
        if user.age > 18 {
            println!("{} ({}) - {}", user.name, user.age, user.email);
        }
    }
    Ok(())
}

Почему это работает: Serde — стандартная библиотека сериализации в Rust. Промт чётко описывает структуру данных и фильтр, что позволяет модели сгенерировать рабочий код без лишнего бойлерплейта.


5. Оптимизация по памяти с помощью аллокаторов

Для чего: Написать код, который использует кастомный аллокатор (например, jemalloc) для снижения фрагментации памяти.

Промт:

Напиши пример на Rust, который:
- использует крейт jemallocator (версия 0.5+)
- создаёт вектор из 1_000_000 элементов типа u64
- замеряет время выполнения и пиковое потребление памяти через std::time::Instant
- сравнивает с глобальным аллокатором (std::alloc::System)
Выведи код с комментариями. Версия Rust: 1.85.

Пример использования:

use std::time::Instant;

#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn main() {
    let start = Instant::now();
    let data: Vec<u64> = (0..1_000_000).collect();
    let duration = start.elapsed();
    println!("Time: {:?}, Len: {}", duration, data.len());
}

Почему это работает: Промт фокусируется на конкретной оптимизации (jemalloc) и добавляет метрики. Это полезно для системного программирования, где важна производительность.


6. Генерация WebAssembly-модуля

Для чего: Создать WASM-модуль на Rust, который можно вызвать из JavaScript.

Промт:

Напиши Rust-код для WebAssembly, который:
- использует wasm-bindgen 0.2.x
- экспортирует функцию add(a: i32, b: i32) -> i32
- не использует std (no_std)
- компилируется в wasm32-unknown-unknown
- включает комментарии с инструкцией по сборке (wasm-pack build --target web)
Выведи только код. Версия Rust: 1.85.

Пример использования:

#![no_std]

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Почему это работает: no_std гарантирует, что модуль будет лёгким. Промт явно указывает цель (wasm32-unknown-unknown) и инструмент сборки (wasm-pack), что устраняет двусмысленность.


7. Парсинг JSON с вложенными структурами

Для чего: Разобрать сложный JSON с вложенными объектами и массивами.

Промт:

Напиши Rust-программу, которая:
- использует serde_json 1.x
- определяет структуры для JSON вида:
  {
    "users": [
      {
        "id": 1,
        "name": "Alice",
        "address": {
          "city": "Moscow",
          "zip": "101000"
        }
      }
    ]
  }
- выводит имена пользователей и их города
- обрабатывает ошибки через unwrap_or_else
Выведи только код. Версия Rust: 1.85.

Пример использования:

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Address {
    city: String,
    zip: String,
}

#[derive(Debug, Deserialize)]
struct User {
    id: u32,
    name: String,
    address: Address,
}

#[derive(Debug, Deserialize)]
struct Data {
    users: Vec<User>,
}

fn main() {
    let json_str = r#"{"users":[{"id":1,"name":"Alice","address":{"city":"Moscow","zip":"101000"}}]}"#;
let data: Data = serde_json::from_str(json_str).unwrap_or_else(

|e| {
        eprintln!("Parse error: {}", e);
        std::process::exit(1);
    });
    for user in &data.users {
        println!("{} lives in {}", user.name, user.address.city);
    }
}

Почему это работает: Промт даёт конкретный пример JSON, что исключает разночтения. Вложенные структуры требуют явного определения типов — модель генерирует их автоматически.


8. Работа с многопоточностью через Rayon

Для чего: Параллельно обработать большой массив данных.

Промт:

Напиши Rust-программу, которая:
- использует крейт rayon 1.9+
- создаёт вектор из 10_000_000 чисел
- параллельно вычисляет квадрат каждого числа через par_iter
- замеряет время выполнения по сравнению с последовательным iter
- выводит оба времени
Выведи только код. Версия Rust: 1.85.

Пример использования:

use rayon::prelude::*;
use std::time::Instant;

fn main() {
    let data: Vec<u64> = (0..10_000_000).collect();

    let start = Instant::now();
let _sequential: Vec<u64> = data.iter().map(

|x| x * x).collect();
    let seq_time = start.elapsed();

    let start = Instant::now();
let _parallel: Vec<u64> = data.par_iter().map(

|x| x * x).collect();
    let par_time = start.elapsed();

    println!("Sequential: {:?}, Parallel: {:?}", seq_time, par_time);
}

Почему это работает: Rayon — стандарт для параллельных вычислений в Rust. Промт просит сравнение с последовательным кодом, что даёт наглядную демонстрацию ускорения.


9. Создание кастомного итератора

Для чего: Реализовать трейт Iterator для пользовательской структуры.

Промт:

Напиши Rust-код, который:
- определяет структуру Fibonacci с полями a и b (тип u128)
- реализует трейт Iterator для Fibonacci, генерируя бесконечную последовательность Фибоначчи
- в main выводит первые 20 чисел через take(20)
- использует impl Iterator
Выведи только код. Версия Rust: 1.85.

Пример использования:

struct Fibonacci {
    a: u128,
    b: u128,
}

impl Fibonacci {
    fn new() -> Self {
        Fibonacci { a: 0, b: 1 }
    }
}

impl Iterator for Fibonacci {
    type Item = u128;

    fn next(&mut self) -> Option<Self::Item> {
        let current = self.a;
        self.a = self.b;
        self.b = current + self.b;
        Some(current)
    }
}

fn main() {
    for (i, val) in Fibonacci::new().take(20).enumerate() {
        println!("F{}: {}", i, val);
    }
}

Почему это работает: Реализация итераторов — частая задача в Rust. Промт чётко указывает тип (u128) и метод (take), что предотвращает переполнение.


10. Интеграция с C через FFI

Для чего: Вызвать C-функцию из Rust с помощью extern "C".

Промт:

Напиши Rust-программу, которая:
- объявляет внешнюю C-функцию: double sqrt(double x) из libm
- вызывает её через unsafe и extern "C"
- выводит результат для x = 2.0
- использует std::os::raw::c_double
Выведи только код. Версия Rust: 1.85.

Пример использования:

use std::os::raw::c_double;

extern "C" {
    fn sqrt(x: c_double) -> c_double;
}

fn main() {
    let x: c_double = 2.0;
    unsafe {
        let result = sqrt(x);
        println!("sqrt({}) = {}", x, result);
    }
}

Почему это работает: Промт использует стандартную C-библиотеку (libm), которая доступна на всех платформах. Это безопасный пример FFI без сторонних зависимостей.


11. Работа с большими файлами через mmap

Для чего: Отобразить файл в память для быстрого чтения без копирования.

Промт:

Напиши Rust-программу, которая:
- использует крейт memmap2 0.9+
- открывает файл "large.bin" (если не существует, создаёт с 1_000_000 байт)
- отображает его в память через Mmap
- читает первые 100 байт и выводит их как срез
- обрабатывает ошибки через anyhow
Выведи только код. Версия Rust: 1.85.

Пример использования:

use memmap2::Mmap;
use std::fs::File;
use anyhow::Result;

fn main() -> Result<()> {
    let file = File::open("large.bin")?;
    let mmap = unsafe { Mmap::map(&file)? };
    let first_hundred = &mmap[..100.min(mmap.len())];
    println!("First 100 bytes: {:?}", first_hundred);
    Ok(())
}

Почему это работает: memmap2 — популярная библиотека для работы с mmap. Промт включает создание файла для теста, что делает пример самодостаточным.


12. Генерация документации с примерами

Для чего: Создать doc-комментарии с примерами кода, которые будут тестироваться через cargo test.

Промт:

Напиши функцию на Rust с именем factorial(n: u64) -> u64, которая:
- вычисляет факториал рекурсивно
- содержит doc-комментарии с описанием, аргументами, паникой (если n > 20)
- включает секцию ```rust с примером использования, который будет работать как doctest
- использует #[must_use]
Выведи только код. Версия Rust: 1.85.

Пример использования:

/// Вычисляет факториал числа n.
///
/// # Arguments
/// * `n` - Неотрицательное целое число (до 20, чтобы избежать переполнения u64)
///
/// # Panics
/// Паникует, если n > 20, так как результат не помещается в u64.
///
/// # Examples
/// ```
/// let result = factorial(5);
/// assert_eq!(result, 120);
/// ```
#[must_use]
pub fn factorial(n: u64) -> u64 {
    if n > 20 {
        panic!("n must be <= 20");
    }
    match n {
        0 | 1 => 1,
        _ => n * factorial(n - 1),
    }
}

Почему это работает: Doc-тесты — встроенная возможность Rust. Промт просит #[must_use] и ограничение на n, что делает код надёжным.


13. Оптимизация с помощью профилирования

Для чего: Добавить инструменты профилирования (CPU, память) в программу.

Промт:

Напиши Rust-программу, которая:
- использует крейт cpuprofiler 0.1+ для профилирования CPU
- создаёт цикл из 1_000_000 итераций с вычислением синуса
- запускает профилировщик на время цикла
- выводит сообщение "Profiling done" после остановки
Выведи только код. Версия Rust: 1.85.

Пример использования:

use cpuprofiler::PROFILER;

fn main() {
    PROFILER.lock().unwrap().start("./profile.prof").unwrap();
    for i in 0..1_000_000 {
        let _ = (i as f64).sin();
    }
    PROFILER.lock().unwrap().stop().unwrap();
    println!("Profiling done");
}

Почему это работает: Профилирование — ключевой навык в системном программировании. Промт использует простой крейт, который генерирует файл для pprof.


14. Работа с асинхронностью через Tokio

Для чего: Написать асинхронный HTTP-клиент, который выполняет несколько запросов параллельно.

Промт:

Напиши Rust-программу, которая:
- использует tokio 1.x и reqwest 0.12+
- создаёт список URL: ["https://httpbin.org/delay/1", "https://httpbin.org/delay/2"]
- выполняет GET-запросы параллельно через tokio::join!
- выводит статус-коды и длину тела
- использует #[tokio::main]
Выведи только код. Версия Rust: 1.85.

Пример использования:

use reqwest::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();
    let urls = vec![
        "https://httpbin.org/delay/1",
        "https://httpbin.org/delay/2",
    ];

let responses = futures::future::join_all(urls.iter().map(

|url| client.get(*url).send())).await;

    for (i, resp) in responses.iter().enumerate() {
        match resp {
            Ok(r) => println!("URL {}: status {}, body len {}", i, r.status(), r.content_length().unwrap_or(0)),
            Err(e) => eprintln!("URL {}: error {}", i, e),
        }
    }
    Ok(())
}

Почему это работает: Tokio — стандартный асинхронный рантайм. Промт использует join_all для параллелизации, что экономит время.


15. Парсинг аргументов командной строки вручную

Для чего: Разобрать аргументы без крейтов, используя std::env::args.

Промт:

Напиши Rust-программу, которая:
- получает аргументы через std::env::args()
- если передан --help, выводит справку
- если передан --name <value>, выводит "Hello, <value>!"
- иначе выводит "Usage: ..."
- не использует сторонние крейты
Выведи только код. Версия Rust: 1.85.

Пример использования:

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    match args.as_slice() {
        [_, flag, value] if flag == "--name" => println!("Hello, {}!", value),
        [_, flag] if flag == "--help" => println!("Usage: program --name <name>"),
        _ => println!("Usage: program --name <name>"),
    }
}

Почему это работает: Промт учит работе с сырыми аргументами — полезно для минималистичных утилит или когда не хочется подключать clap.


Заключение

Мы разобрали 15 промтов, покрывающих ключевые области Rust: от системного программирования (FFI, mmap, профилирование) до практических утилит (CLI, парсинг, асинхронность). Каждый промт можно адаптировать под свой проект — меняйте типы, названия или добавляйте условия.

Чтобы получить максимальную пользу:
1. Указывайте версию Rust — это предотвращает устаревшие конструкции.
2. Добавляйте конкретные примеры входных данных — модель даст точный код.
3. Тестируйте результат через cargo check — многие ошибки отлавливаются на этапе компиляции.

Попробуйте применить эти промты в своём следующем проекте: CLI-утилите, WASM-модуле или высоконагруженном сервере. Rust — это язык, где правильный промт экономит часы отладки.

← Все статьи

Комментарии

Читайте также

10 промтов для UI/UX дизайна: Figma, прототипы, компоненты

18 июля 2026

Цифровая трансформация рынка труда: институционализация профессий и персонализация карьерных стратегий в 2026 году

18 июля 2026

Как подключить Reddit к AI-агенту ASI Biont: автоматизация мониторинга и анализа обсуждений без программирования

18 июля 2026

Бесперебойные платежи: как интеграция ASI Biont с YooKassa автоматизирует выставление счетов и сверку

18 июля 2026

Как подключить AI-агента к SendGrid: пошаговое руководство по автоматизации email-рассылок без программирования

18 июля 2026

От сценария к экрану: Как курс «Кино- и видеопроизводство» от Asibiont превращает начинающих кинематографистов в рассказчиков

18 июля 2026

Z-Wave и AI-агент ASI Biont: интеграция умного дома без программирования за 30 минут

18 июля 2026

Промышленный интернет вещей (IIoT) и SCADA-системы: ваш путь к Индустрии 4.0 — практический обзор курса

18 июля 2026

Освойте налоговое право Российской Федерации: Практическое руководство с ИИ на Asibiont

18 июля 2026