Вот так Chat GPT представила человека, если бы это был язык Rust
Вот так Chat GPT представила человека, если бы это был язык Rust

Я CEO своей компании MediaRise (компания только начала развиваться), с техническим бэкграундом. Сам люблю писать на разных языках, а вернее пробовать работать с ними. Давно уже слышал о таком языке как Rust.

Rust — это современный системный язык программирования, разработанный для обеспечения высокой производительности и безопасности, особенно при работе с конкурентными процессами. Изначально он был разработан компанией Mozilla, а сейчас поддерживается фондом Rust Foundation. Rust приобретает все большую популярность благодаря своей надежности и эффективности.

Ключевые особенности Rust:

Ключевые особенности Rust:

  1. Безопасность памяти: Rust устраняет общие ошибки программирования, такие как разыменование нулевого указателя и переполнение буфера, благодаря строгой проверке на этапе компиляции, без использования сборщика мусора.

  2. Система владения: Уникальная система владения Rust обеспечивает безопасность памяти без необходимости в сборщике мусора. Она использует систему владения с правилами, которые проверяются компилятором на этапе компиляции.

  3. Конкурентность: Rust упрощает написание конкурентных программ, предотвращая состояния гонки на этапе компиляции благодаря концепциям владения и заимствования.

  4. Производительность: Rust разрабатывался с целью быть таким же быстрым, как и C++, и часто демонстрирует сопоставимую производительность. Он может использоваться для системного программирования, где критична производительность.

  5. Выразительная типовая система: Rust обладает мощной типовой системой, включающей такие возможности, как сопоставление с образцом, алгебраические типы данных и обобщенные типы на основе трейтов, что позволяет писать более выразительный и безопасный код.

  6. Cargo: Rust поставляется с Cargo, системой сборки и менеджером пакетов, который упрощает управление зависимостями, сборку и распространение кода.

  7. Экосистема: Экосистема Rust включает растущую коллекцию библиотек и инструментов, которые помогают разработчикам писать надежный и эффективный код. Официальный реестр пакетов, crates.io, содержит тысячи библиотек с открытым исходным кодом.

Сферы применения Rust:

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

  2. WebAssembly: Rust может компилироваться в WebAssembly, что позволяет запускать код Rust в веб-браузерах с производительностью, близкой к нативной.

  3. Сетевое программирование: Особенности безопасности и производительность Rust делают его подходящим для написания сетевого ПО, включая веб-серверы и клиенты.

  4. Разработка игр: Производственные характеристики Rust делают его хорошим выбором для разработки игр, где скорость и эффективность критичны.

  5. Командные утилиты: Менеджер пакетов Cargo упрощает создание и распространение командных утилит.

Известные проекты, использующие Rust:

  1. Firefox Quantum: Mozilla использовала Rust для переписывания частей их движка браузера, что привело к значительному улучшению производительности.

  2. Dropbox: Dropbox использует Rust для некоторых своих серверных сервисов.

  3. Cloudflare: Cloudflare использует Rust для нескольких своих производительно критичных сервисов.

  4. Rustlings: Образовательный проект, который помогает изучать Rust через небольшие упражнения.

Комбинация безопасности, производительности и поддержки конкурентности делает Rust привлекательным выбором для многих видов разработки программного обеспечения. Его растущая популярность и активное сообщество гарантируют, что Rust продолжит развиваться и улучшаться.

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

Понимаю, что существуют готовые решения, но захотелось создать свой "велосипед" и опробовать новый для себя язык — Rust.

Идея есть, с созданием Telegram-бота проблем нет, но возникла проблема с сервисом, который будет переводить с одного языка на другой. Выбор пал на LibreTranslate. Чтобы использовать его бесплатно, необходимо развернуть приложение на своем сервере. Я так и сделал: установил зависимости и развернул в Docker-контейнере. Проблем не возникло, единственное, что приложение необходимо запускать с флагом: `./run.sh --api-keys`, чтобы можно было получить `api_key`. Подробнее о настройке и получении `api-key` для LibreTranslate можно прочитать на официальном сайте.

Развернув сервер LibreTranslate и получив токен для Telegram-бота, осталось реализовать приложение. Просмотрев официальную документацию по Rust и наработки на GitHub, я начал творить. Установил Rust и Cargo (регистр/менеджер пакетов для Rust). Изучив документацию библиотеки teloxide для создания Telegram-ботов на Rust, написал обработчик для событий сообщений в чате.

#[tokio::main]
async fn main() -> ResponseResult<()> {
    dotenv().ok();
    env_logger::init();
    let token_bot = env::var("TELEGRAM_BOT_KEY").expect("TELEGRAM_BOT_KEY not found");

    let bot = teloxide::Bot::new(&token_bot).parse_mode(ParseMode::Html);

    // Create a handler for our bot, that will process updates from Telegram
    let handler = dptree::entry()
        .inspect(|u: Update| {
                    eprintln!("{u:#?}"); // Print the update to the console with inspect
        })

   ...

        .branch(
            Update::filter_message()
                .branch(
                    dptree::endpoint(translate_message),
                )
        );

    // Create a dispatcher for our bot
    Dispatcher::builder(bot, handler).enable_ctrlc_handler().build().dispatch().await;

    Ok(())
}

async fn translate_message(bot: Bot, msg: Message) -> ResponseResult<()> {
    if let Some(text) = msg.text() {

        match translate(text).await {
            Ok(translated_word) => {
                bot.send_message(msg.chat.id, translated_word).await?;
            }
            Err(e) => {
                bot.send_message(msg.chat.id, format!("Translation error: {}", e)).await?;
            }
        }
    } else {
        bot.send_message(msg.chat.id, "Send me plain text.").await?;
    }

    Ok(())
}

Далее саму функцию для запроса перевода с API LiberTranslate. Приложение по переводу определяет на каком языке сообщение и переводит на необходимый (ru -> th, th -> ru)

async fn translate(text: &str) -> ResponseResult<String> {
    let client = reqwest::Client::new();

    let api_translate_url = env::var("API_TRANSLATE_URL").expect("API_TRANSLATE_URL not found");
    let api_translate_key = env::var("API_TRANSLATE_KEY").expect("API_TRANSLATE_KEY not found");
    let api_detect_url = env::var("API_DETECT_URL").expect("API_DETECT_URL not found");
    eprintln!("{text:#?}");

    let detect_request = DetectRequest {
        q: String::from(text),
        api_key: String::from(api_translate_key.clone()),
    };

    let res = client.post(api_detect_url)
        .header("Content-Type", "application/x-www-form-urlencoded")
        .form(&detect_request)
        .send()
        .await?;
    let resp_json = res.json::<Vec<DetectResponse>>().await?;

    let lang = &resp_json[0].language;

    eprintln!("{lang:#?}");
    let target_lang = if lang == "ru" { "th" } else { "ru" };

    let json_object = json!({
                "q": text,
                "source": "auto",
                "target": target_lang,
                "format": "text",
                "alternatives": 3,
                "api_key": api_translate_key
            });

    let json_string = serde_json::to_string(&json_object).unwrap();


    let res = client.post(api_translate_url)
        .body(json_string)
        .header("Content-Type", "application/json")
        .send()
        .await?;

    let resp_json = res.json::<TranslateResult>().await?;
    let translated_word = resp_json.translatedText;
    Ok(translated_word)
}

Результат в Telegram чате

Изображение с чата
Изображение с чата

Были проблемы с багами, которые были из-за того, что я использовал старые библиотеки на Rust, когда пытался проблему решить с помощью ChatGPT. Но больше помог живой опыт разработчиков с GitHub, где я смотрел реализацию какого либо функционала: API документация бота, работа с env (файлами окружения), примеры работы с json, отправка rest запросов и также работу конструкции языка.

Я очень рад рабочему приложению, потому что ранее не писал на Rust и это меня вдохновило изучать его дальше. Опытные разработчики наверняка подскажут, как можно оптимизировать код, чему я буду очень рад.

Осталось сбилдить приложение и запустить его в режиме демона на сервере

Настройка systemd

Соберите ваше приложение с помощью команды:

cargo build --release

Создайте файл юнита для systemd. Например, создадим файл /etc/systemd/system/translate_bot.service

[Unit]
Description=Translate Bot
After=network.target

[Service]
ExecStart=/path/to/your/application
Restart=always
User=yourusername
Group=yourgroupname
Environment=/path/to/your/.env
WorkingDirectory=/path/to/your/application/directory

[Install]
WantedBy=multi-user.target

Перезагрузите конфигурацию systemd, чтобы он узнал о новом сервисе:

sudo systemctl daemon-reload

Запустите сервис:

sudo systemctl start translate_bot

Убедитесь, что сервис запущен и работает:

sudo systemctl status translate_bot

Чтобы ваш сервис автоматически запускался при старте системы, выполните команду:

sudo systemctl enable rust_service

Ваше приложение на Rust будет работать как системный сервис, управляемый systemd. Вы можете контролировать его с помощью стандартных команд systemd, таких как start, stop, restart, и status.

P.S. Хотел бы также решить проблему с env файлами, чтобы доступ к ним был в функции из main.

Далее в планах: я бы хотел реализовать обработку события, если в чате появится новый user (а также ливнет). User может выбрать язык, на котором бы он хотел получать перевод. Сами юзеры и их настройки будут храниться в базе PostgreSQL

Всем спасибо за внимание! Исходники выложил на GitHub.

Исходник на GitHub

Комментарии (24)


  1. PeopleMax
    21.07.2024 15:48

    Интересно, какой в итоге язык будет более популярным, rust или go. Я почему то думаю что go. Так сказать у go маркетинг более развит


    1. Ksoo
      21.07.2024 15:48
      +1

      Довольно предсказуемо на данном этапе, golang будет оставаться более популярен, из-за меньшего порога входа и достаточной универсальности.


      1. AdVv
        21.07.2024 15:48
        +1

        Rust имеет уникальные возможности. А что уникального может предложить golang ?


        1. taslismanfr
          21.07.2024 15:48

          Время и деньги. Если rust сможет решать задачи бизнеса минимизируя эти параметры лучше чем go, то тогда он станет популярнее.


        1. sdramare
          21.07.2024 15:48

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


    1. JekaMas
      21.07.2024 15:48
      +4

      Go. Он проще. Ровно так же у простых языков популярность всегда выше.


      1. sdramare
        21.07.2024 15:48

        Еще важным фактором является компания-локомотив, которая будет продвигать язык через свои продукты. У C# есть MS, у Go гугл, у Kotlin JetBrains и т.д. А раст все свои годы существует как интересный язык, у которого за плечами ни больших проектов, ни вакансий.


        1. JekaMas
          21.07.2024 15:48

          Вакансии - это да. Выбор их стал лучше, но всё ещё очень ограничен. Хотя производительность на расте, по ощущениям, на попядок выше гошки в типовых задачах.


          1. sdramare
            21.07.2024 15:48

            В типовых задачах(CRUD с перекладыванием JSON), практически никогда язык не будет боттлнеком на фоне чтения из базы, редиса, кафки и api коллов к другим сервисам. Зато время разработки на расте, особенно на этапе MVP, занимает в разы, а то и на порядок больше, чем на языках с GC. Я уже не говорю про то, что в момент, когда у вас в коде появится что-то типа Arc<Mutex<HashMap<_>>>(а оно появится), о перфомансе в принципе можно будет перестать говорить.


    1. lorc
      21.07.2024 15:48
      +2

      Я не думаю что rust и go нацелены на одну и ту же нишу. Rust - это попытка заменить в С в задачах системного программирования. Его поддержку уже втянули в Linux kernel и например в OP-TEE.

      Golang - же в ядре никогда не будет поддерживаться. У него совершенно иная ниша - прикладной софт.

      Они не конкурируют между собой, поэтому вопрос что будет более популярным - не имеет особого смысла. Это как сравнивать по популярности картошку и авокадо. Да, картошка безусловно популярнее. Но вы не будете класть картошку в блюда, где по рецепту должен быть авокадо.


  1. Lev3250
    21.07.2024 15:48
    +8

    Я CEO своей компании MediaRise (компания только начала развиваться)

    Hidden text


    1. Virviil
      21.07.2024 15:48
      +2

      Ну как бы по формату и слогу статьи все было понятно и так...


      1. Digkill
        21.07.2024 15:48

        Что тебе понятно? ты ванга, или мракобес? Возможно просто ты никчемный, поэтому решил на какать тут?


  1. Akuma
    21.07.2024 15:48
    +4

    Rust для перекладывания json-ов - это ужасный выбор. Чисто как попробовать можно, но довольно бессмысленно.


  1. sdramare
    21.07.2024 15:48

    А зачем здесь раст если 99.999999% времени приложения просто будет ждать вот здесь ответа let res = client.post(api_detect_url)

    Такое приложение можно было бы написать хоть на питоне, при этом вышло бы в 10 раз быстрее и в 10 раз лаконичней без заметной потери в производительности.

    И зачем было брать

    env_logger::init();

    Если вы потом всеравно напрямую пишите в io::stderr типа eprintln!("{lang:#?}");

    И почему туда летят просто отладочные сообщения?

    Не надо явно создавать json строки, http клиент в расте(request) имеет метод .json(&data) в билдере, надо фичу json включить для этого.


    1. MountainGoat
      21.07.2024 15:48

      Rust над Питоном в таких случаях выбирать есть смысл в одной ситуации: планируется версия для Android или WebAsm. У Питона с этим до сих пор хреновенько, по сравнению с ним Rust входит с ноги. Ну или хочется скомпилированную программу под десктоп, чтоб не совсем уж кто хочет ковырялся в твоих исходниках.


      1. sdramare
        21.07.2024 15:48

        Ну питон я привел как пример языка с низкой производительностью, а так можно взять любой язык с GC и для Android и для декстопа и получить не хуже перфоманс и гораздо дешевле стоимость разработки.


    1. Digkill
      21.07.2024 15:48

      я написал бота за 1 день, до этого ни разу не используя Rust. Поэтому ошибок куча, я хотел просто попробовать rust в деле, но с такой токсичной аудиторией как в помойке хабра, лучше сюда статьи никогда не выкладывать.


      1. Dartess
        21.07.2024 15:48

        Согласен, лучше!

        Ещё можно комментарии не писать, ну её, эту аудиторию.


        1. AlexZyl
          21.07.2024 15:48

          Автору так нетерпелось поругать хабр что он аж свою консерву двенадцатиледней давности вскрыл.
          @moderator


          1. Digkill
            21.07.2024 15:48

            ну это уже все знают, в хабре самые никчемные сидят, помойка рунета, все адекватные уже давно на dev и редите


      1. sdramare
        21.07.2024 15:48

        Так а какой реакции вы ожидали на такую статью? "Чел, ты молодец, что попробовал что-то новое для себя, круто что тебя это вдохновляет"? Ну даже в этом случае, лучше было бы тогда сделать упор на персональный опыт, типа "вот я всю жизнь писал на php, а теперь попробовал сделать протенькую программу на расте, вот что мне понравилось, а вот что нет".


      1. ivanuzzo
        21.07.2024 15:48

        1 день ? Я перед тем как писать на Rust месяц только на документацию потратил, прошел через боль - настолько было тяжело после динамических языков типа JS и Python. Вы даже не попробовали Раст, считайте, а уже бросились писать статью. Могли бы пойти более простым путем - попросить chatGPT написать код для вас и написать статью об этом.

        необязательно свой первый опыт тут же тащить на хабр - такие статьи только засоряют эфир. Вы бы лучше развили свой проект, столкнулись бы с рядом трудностей и после этого написали бы статью, как вы эффективно решили какую-то проблему - такая статья пригодилась бы людям и принесла бы пользу.


        1. Digkill
          21.07.2024 15:48

          уебись об стену, дура с 1 месяцем документации, а я за 1 день рабочий код написал