Почему Rust — это ваш козырь в портфолио
Если вы читаете эту статью, то, скорее всего, уже знаете, что Rust — это не просто очередной модный язык. Это технология, которую обожают в FAANG и хайповых стартапах. Но одно дело — сказать в резюме «Знаю Rust», и совсем другое — показать работающий проект. Без портфолио даже гениальный код останется просто текстом в текстовом редакторе.
В этой статье мы не будем обсуждать синтаксис или учить вас основам. Мы пойдём дальше: я покажу вам 5 реальных идей для проектов, которые закроют потребности рынка и заставят рекрутера кликнуть на ваше резюме. Каждый проект — это не просто «тудушка», а полноценный инструмент, который вы сможете показать на собеседовании или выложить на GitHub.
Бонус: я добавил примеры кода, чтобы вы могли сразу начать. Поехали!
Проект №1: CLI-утилита для анализа логов
Самый быстрый способ войти в мир Rust — написать что-то полезное для командной строки. CLI-утилиты — это хлеб с маслом для Rust-разработчика. Они быстрые, безопасные и идеально подходят для демонстрации навыков работы с std::fs, clap и обработкой ошибок.
Что делает этот проект?
Утилита log-analyzer читает текстовый файл с логами (например, из Nginx или вашего приложения) и выдаёт статистику: количество ошибок, самые частые IP-адреса, временные метки. Всё это — с цветным выводом в терминал.
Почему это круто для портфолио?
- Работа с файловой системой и потоками
- Парсинг строк с использованием регулярных выражений или
nom - Аргументы командной строки (крейт
clap) - Вывод в цвете (крейт
colored)
Пример кода
use clap::Parser;
use std::fs::File;
use std::io::{BufRead, BufReader};
#[derive(Parser)]
#[command(name = "log-analyzer")]
struct Args {
#[arg(short, long)]
file: String,
}
fn main() {
let args = Args::parse();
let file = File::open(&args.file).expect("Не удалось открыть файл");
let reader = BufReader::new(file);
let mut error_count = 0;
for line in reader.lines() {
let line = line.unwrap();
if line.contains("ERROR") || line.contains("error") {
error_count += 1;
}
}
println!("Найдено ошибок: {}", error_count);
}
Совет: Добавьте обработку аргументов через clap и поддержку формата JSON. Это покажет, что вы умеете работать с сериализацией.
Проект №2: Веб-сервер на Actix-web с REST API
Rust — не только про системное программирование. Веб-разработка на Rust набирает обороты, и actix-web — один из самых быстрых фреймворков в мире. Сделайте простой REST API для управления задачами (CRUD). Это классика, но в Rust она выглядит свежо.
Что нужно реализовать?
- Эндпоинты: GET, POST, PUT, DELETE для сущности "Task"
- Хранение данных в памяти (с возможностью расширения до базы данных)
- Валидация входящих данных через
serde - Обработка ошибок и возврат корректных HTTP-статусов
Почему это добавит веса портфолио?
Вы покажете, что понимаете, как строить современные API. Работодатели ищут людей, которые могут написать не только скрипт, но и серверную часть. Плюс, actix-web — это отличный способ продемонстрировать знание асинхронности и многопоточности.
Код для старта
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::Mutex;
#[derive(Serialize, Deserialize, Clone)]
struct Task {
id: u32,
title: String,
completed: bool,
}
struct AppState {
tasks: Mutex<Vec<Task>>,
}
async fn get_tasks(data: web::Data<AppState>) -> impl Responder {
let tasks = data.tasks.lock().unwrap();
HttpResponse::Ok().json(tasks.clone())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let app_state = web::Data::new(AppState {
tasks: Mutex::new(vec![]),
});
HttpServer::new(move || {
App::new()
.app_data(app_state.clone())
.route("/tasks", web::get().to(get_tasks))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Дополните: добавьте Swagger-документацию через utoipa — это покажет ваш уровень.
Проект №3: Парсер веб-страниц на Rust
Парсеры — это золотая жила для портфолио. Они показывают, что вы умеете работать с сетью, HTML и структурами данных. В Rust для этого есть отличные крейты: reqwest для HTTP-запросов и scraper для разбора HTML.
Идея: парсер заголовков новостей
Напишите программу, которая заходит на любой новостной сайт (например, Habr или Lenta) и собирает все заголовки статей с первой страницы. Результат сохраняйте в CSV или JSON.
Чем это полезно?
- Работа с асинхронными HTTP-запросами
- Парсинг HTML с помощью CSS-селекторов
- Сериализация данных
- Обработка ошибок сети и таймаутов
Пример кода
use reqwest;
use scraper::{Html, Selector};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let html = reqwest::get("https://news.ycombinator.com/")
.await?
.text()
.await?;
let document = Html::parse_document(&html);
let selector = Selector::parse(".titleline > a").unwrap();
for element in document.select(&selector) {
let title = element.text().collect::<String>();
println!("{}", title);
}
Ok(())
}
Усложните: добавьте многопоточность для обхода нескольких страниц и защиту от блокировок (User-Agent, задержки).
Проект №4: Собственная реализация grep
Вы когда-нибудь задумывались, как работает утилита grep? Напишите свою! Это не так сложно, как кажется, но даёт глубокое понимание работы