Задать вопрос
Ответы пользователя по тегу Rust
  • Можно ли вызвать ошибку времени компиляции в макросе?

    vabka
    @vabka Куратор тега Rust
    Ну if ты не можешь туда впихнуть, но ты можешь сделать что-то типа
    macro_rules! macro {
     (5) => {compile_error! ("5 is unacceptable")}
    }

    https://doc.rust-lang.org/std/macro.compile_error.html

    Делать какие-то сложные проверки с условиями ты в декларативных макросах не можешь.
    Например ты не можешь вычислить значение выражения. И не можешь убедиться, что это значение константное.
    Так что иногда придётся делать динамические проверки, добавляя всякие if-ы и assert-ы
    Ответ написан
    Комментировать
  • Как проверить удерживается ли клавиша на Windows os?

    vabka
    @vabka Куратор тега Rust
    Под виндой ты можешь попробовать крейт windows и функцию GetKeyState:
    https://docs.microsoft.com/en-us/windows/win32/api...
    cargo.toml
    [package]
    name = "windows_key_press"
    version = "0.1.0"
    edition = "2021"
    
    
    [dependencies.windows]
    version = "0.37.0"
    features = ["Win32_UI_Input_KeyboardAndMouse"]

    main.rs

    use std::thread;
    use windows::Win32::UI::Input::KeyboardAndMouse::{GetKeyState};
    fn main() {
        const VK_SPACE: i32 = 0x20;
        const HIGHER_ORDER_BIT: i16 = -128;
        loop {
            let state = unsafe { GetKeyState(VK_SPACE) };
            let is_up = state & HIGHER_ORDER_BIT == 0;
            println!("{}", is_up);
            thread::sleep(std::time::Duration::from_millis(100));
        }
    }
    Ответ написан
    Комментировать
  • Как правильно написать макрос для такого выражения?

    vabka
    @vabka Куратор тега Rust
    Вот эта ошибка:
    missing tokens in macro arguments

    Означает, что раст не может сматчить макрос с таким аргументом. Дело в том, что "1" не является BlockExpression, который ты ожидаешь в начале (https://doc.rust-lang.org/reference/expressions/bl...)

    Вот примерно рабочий макрос, который ничего не делает.
    macro_rules! name {
        ($t: ty, $({$($el:expr ),*}),*) => {42};
        
    }
    fn main() {
        name!(i32, {1, 2, 3 ,4}, {1,2});
    }
    Ответ написан
  • Как убрать кавычки в результате вывода содержимого файла после его чтения в Rust?

    vabka
    @vabka Куратор тега Rust
    {:?} использует Debug для форматирования. В твоём случае он тебе не нужен.

    Попробуй вот так:
    #[get("/index")]
    pub async fn index() -> impl Responder {
        let path = Path::new("test.txt");
        spawn_blocking(|| cat(path)).await?
    }
    
    fn cat(path: &Path) -> io::Result<String> {
        let mut f = File::open(path)?;
        let mut s = String::new();
        match f.read_to_string(&mut s) {
            Ok(_) => Ok(s),
            Err(e) => Err(e),
        }
    }


    Кстати, твоя функция cat использует синхронный IO, так что её следует вызывать в spawn_blocking.
    Но лучше будет перейти на tokio или async_std
    Ответ написан
    3 комментария
  • Есть ли аналог curl для Rust?

    vabka
    @vabka Куратор тега Rust
    Оставлю ответ для будущих поколений.
    Есть вполне хороший пакет - reqwest.
    https://github.com/seanmonstar/reqwest

    Код будет такой:
    (сначала надо добавить зависимость)
    [dependencies]
    reqwest = { version = "0.11", features = ["blocking", "json"] } #blocking - только для примера, чтобы не нагружать await-ами. json - чтобы добавить возможность десериализации ответа при помощи serde-json


    use std::collections::HashMap;
    
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        let resp = reqwest::blocking::get("https://httpbin.org/ip")?
            .json::<HashMap<String, String>>()?; // Тут нужно подставлять тот тип, который реализует трейт Deserialize
        println!("{:#?}", resp);
        Ok(())
    }
    Ответ написан
    Комментировать
  • Странный дизайн Rust?

    vabka
    @vabka Куратор тега Rust
    Во первых, почему указатели в Rust называются ссылками?

    Потому что в Rust есть свои типа умные ссылки, которые проверяются борроу-чекером - &T и &mut T.
    А есть сырые указатели, которые *const T и *mut T;

    Разница в том, что первые проверяются борроу-чекером, а вторые - нет.
    Первые можно безопасно разыменовать и обращаться к данным, а вторые - нет.

    Вот как это вместить - после плюсов вызывает неприязнь.

    Просто забыть привычки от C++ и плюсовую терминологию, и использовать новую.
    У вас же при изучении нового человеческого языка не возникает проблем от того что какой-нибудь кот называется кэт-ом?
    Ответ написан
    Комментировать
  • Rust мёртв, или только развивается?

    vabka
    @vabka Куратор тега Rust
    Rust появился в 2006

    Rust перешёл в stable только в 2015.
    До этого это были всякие прототипы и эксперименты.
    на данное время крупных проектов использующие его (кроме дискорда) нет

    https://www.rust-lang.org/production/users
    Как мне кажется, достаточно много разных крупных и именитых продуктов.

    PS: С Rust у тебя бы не возникло таких вопросов:
    https://qna.habr.com/q/1155256
    https://qna.habr.com/q/1147948
    Ответ написан
    Комментировать
  • Какой объем знаний и навыков нужно для того чтобы стать middle Rust разработчиком?

    vabka
    @vabka Куратор тега Rust
    Сейчас редко нанимают чистых растаманов, тк язык молодой.
    Обычно нанимают тех, кто переходит с других, более традиционных языков.
    Так что тебе сначала надо стать мидлом/сеньором в C++/Java/C#/C а потом дотянуть знания раста, чтобы уметь на нём решать задачи, аналогичные тем, которые ты решаешь с основным языком.

    Ну и соответствующий коммерческий опыт ~5 лет.
    Учитывай ещё и специфику Rust-проектов: это что-то новое, что требует безопасности и эффективности, где нельзя/нежелательно/невозможно использовать "Традиционные" языки.
    Так что и уровень ответственности и требуемых знаний будет выше, чем на аналогичную, например Java-позицию.
    Ответ написан
    1 комментарий
  • Как изменить размер консоли в rust?

    vabka
    @vabka Куратор тега Rust
    Насколько я знаю,в c++ несколькими строчками можно задать размер открываемой консоли в пикселях.

    Но только на винде и только с использованием виндовых API, и работать это будет только со старой консолью.
    Для этого есть крейт windows - https://crates.io/crates/windows
    Использовать следует функцию SetConsoleWindowInfo (или какую там ты использовал функцию?):
    https://docs.microsoft.com/en-us/windows/console/s...

    Либо альтернативный вариант, для новой консоли, но уже не в пикселях, а в колонках:
    https://docs.microsoft.com/en-us/windows/console/c...
    Просто пиши в консоль соответствующую последовательность символов (ну или используй какую-нибудь абстракцию типа crossterm или termion)
    Ответ написан
    1 комментарий
  • Зачем писать .to_string() при объявлении строки?

    vabka
    @vabka Куратор тега Rust
    Есть хорошая статья: https://habr.com/ru/post/274485/

    У строковых литералов тип &'static str. Тоесть это заимствованная ссылка на объект с неограниченным временем жизни.
    А to_string возвращает уже owned строку типа std::string::String

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

    Если ты хочешь получить именно String из строкового литерала, то есть сразу несколько вариантов, включая показанный:
    let a: String = String::from("a");
    let b: String = "b".to_string();
    let c: String = "c".into(); // или "c".into::<String>(), если не указывать тип явно.
    let d: String = "d".to_owned();
    Ответ написан
    Комментировать
  • Зачем в Rust fn main() -> io::Result{ писать вот так?

    vabka
    @vabka Куратор тега Rust
    Он же нигде в этом коде не используется

    Используется.
    use std::io;
     
    fn main()  -> io::Result<()>{
         
        let mut input = String::new();
        println!("Введите свое имя: ");
        io::stdin().read_line(&mut input)?; // Тут
        println!("Ваш имя: {}", input);
         
        Ok(()) // И тут
    }
    Ответ написан
    2 комментария
  • Как дебажить Rust в vscode?

    vabka
    @vabka Куратор тега Rust
    Что-то ты намудрил с расширениями.
    1. Rust-analyzer нельзя сочетать с обычным Rust-плагином.
    2. Вместо пака расширений лучше самому всё по отдельности ставить.
    Для отладки нужно lldb расширение.

    После этого rust-analyzer сам создаст тебе конфиг для отладки, при первой попытке дебага.

    Чуть более подробное решение из моего коммента

    WasTabon, в общем вот список моих екстеншенов (копировал extension id чтобы легко можно было найти):
    • vadimcn.vscode-lldb (для отладки)
    • bungcip.better-toml (чтобы была подсветка в cargo.toml)
    • serayuzgur.crates (для автодополнения имён и версий пакетов)
    • matklad.rust-analyzer (самое главное)
    • swellaby.vscode-rust-test-adapter (чтобы тесты запускать через боковую панель)
    • jscearcy.rust-doc-viewer (чтобы документацию удобнее смотреть)

    Все остальные расширения советую удалить дабы точно не было конфликтов.
    Вот мои файлы когда только создал проект:
    61e318cebdcb5121332621.png
    Rust-analyzer сразу добавил линзу "Debug" около мейна, жму на неё.
    61e31954758f4949494249.png
    И вот результат, всё работает:
    61e31968d2461592787549.png

    PS:
    ❯ cargo -V
    cargo 1.58.0 (7f08ace4f 2021-11-24)
    ❯ rustup toolchain list
    stable-x86_64-pc-windows-msvc (default)

    PPS: о launch.json
    Вот тут есть вполне очевидная кнопка/ссылка "create a launch.json file"
    61e319fccc515317499730.png
    При её нажатии возникает вполне понятный вопрос:
    61e31a574f1fc385427254.png
    Если на него ответить "Yes", то в папке .vscode появится файл launch.json с вот таким содержимым:
    {
        // Use IntelliSense to learn about possible attributes.
        // Hover to view descriptions of existing attributes.
        // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "type": "lldb",
                "request": "launch",
                "name": "Debug executable 'rust-demo'",
                "cargo": {
                    "args": [
                        "build",
                        "--bin=rust-demo",
                        "--package=rust-demo"
                    ],
                    "filter": {
                        "name": "rust-demo",
                        "kind": "bin"
                    }
                },
                "args": [],
                "cwd": "${workspaceFolder}"
            },
            {
                "type": "lldb",
                "request": "launch",
                "name": "Debug unit tests in executable 'rust-demo'",
                "cargo": {
                    "args": [
                        "test",
                        "--no-run",
                        "--bin=rust-demo",
                        "--package=rust-demo"
                    ],
                    "filter": {
                        "name": "rust-demo",
                        "kind": "bin"
                    }
                },
                "args": [],
                "cwd": "${workspaceFolder}"
            }
        ]
    }

    Тут у нас появляется две конфигурации - одна для запуска приложения, а другая для запуска тестов.
    61e31abfa7315157464415.png
    Работает эта шняга абсолютно также, как показал выше.
    UPD: оформил в виде статьи https://habr.com/ru/post/645797/
    Ответ написан
  • Можно ли использовать fltk в связке с другими библиотеками rust?

    vabka
    @vabka Куратор тега Rust
    "С другими" - это какими?
    И в каком плане совместимость?

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

    По крайней мере в самом fltk не говорится о том что она что-то ломает. И наоборот.
    Так что тестируй
    Ответ написан
    Комментировать
  • Что выбрать gtk или fltk для написания gui на rust?

    vabka
    @vabka Куратор тега Rust
    Я бы смотрел в сторону html/css, тут есть два варианта:
    azul - быстрый и эффективный по памяти, использует тот же рендер, что и Firefox. Не нужно копаться в js
    tauri - проще, можно визуал делать на любом удобном js-фреймворке + из коробки есть инструменты для создания установщиков для всех платформ и автообновлений (но за это платишь сравнительно большим расходом оперативки)

    Если хочется поверх GTK - druid или vgtk - это лучше чем голые биндинги.
    Ещё есть SixtyFPS - по описанию тоже прикольно. На десктопе использует нативные контролы, но там сложности с лицензией (похоже на Qt, где опенсорс бесплатный, а коммерческую лицензию надо покупать)
    Удобных либ для работы с Qt не нашёл.

    В общем - отталкивайся от задачи, на сколько сложный UI ты хочешь делать.
    Ответ написан
    Комментировать
  • Насколько хорошо подходит Rust для Embedded систем, например модули для wifi роутеров?

    vabka
    @vabka Куратор тега Rust
    Уже можно его брать за основу для продукта или это будет "плакали - кололись и продолжали жевать"?

    Сейчас в целом всё ок, но иногда будет "плакали кололись", особенно если используется какая-то периферия или чип, для которых ещё не написаны готовые библиотеки (или они устарели).
    Ну это по моим ощущениям, тк я пока глубоко не залазил. Со всякими популярными штуками типа stm32-discovery всё ок.
    Ответ написан
    Комментировать
  • Можно ли перевести код из Rust в Python?

    vabka
    @vabka Куратор тега Rust
    В принципе, в общем случае вы можете из раста вызвать интерпретатор питона, а из питона - исполняемый файл или библиотеку, написанную на расте.
    Ответ написан
    Комментировать
  • Как скачать файл по прямой ссылке?

    vabka
    @vabka Куратор тега Rust
    Хз что именно было не так (подозреваю 'add missing generic argument')
    Но вот это работает:
    use std::{fs::OpenOptions, io::Write, path::Path};
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let target = "https://www.rust-lang.org/static/images/rust-logo-blk.svg";
        let response = reqwest::get(target).await?;
    
        let path = Path::new("./image.svg");
        let mut file = OpenOptions::new().create(true).write(true).open(path)?;
        let content = response.text().await?;
        file.write_all(content.as_bytes())?; // Хочу асинхронно писать в файлы. Как это можно сделать?
        Ok(())
    }

    Пример брал из документации reqwest
    Ответ написан
    1 комментарий
  • Существуют ли фреймворки, позволяющие писать бекенд на rust+javascript?

    vabka
    @vabka Куратор тега Веб-разработка
    Фреймворков таких нет, и не понятно, зачем.

    В принципе на бэкенде можно использовать ffi/обёртки над v8/wasm/ всякие RPC поверх чего-угодно, но это всё будут самодельные решения, а не фреймворки.
    Ответ написан
  • Rust unsafe, какие есть подводные камни и как подходить к дизайну C API?

    vabka
    @vabka Куратор тега Rust
    Не пудри себе мозги и возьми уже готовую безопасную обёртку над raylib
    https://crates.io/crates/raylib

    А гайд по работе с unsafe - это rustonomicon

    unsafe сам по себе просто позволяет использовать сырые указатели + вызывать другие unsafe функции.

    Безопасная обётка - это когда ты при помощи типов и всяких валидаций гарантируешь корректное использование.
    Вот пример из того что выше:
    use raylib::prelude::*;
    
    fn main() {
        let (mut rl, thread) = raylib::init()
            .size(640, 480)
            .title("Hello, World")
            .build();
    
        while !rl.window_should_close() {
            let mut d = rl.begin_drawing(&thread);
    
            d.clear_background(Color::WHITE);
            d.draw_text("Hello, world!", 12, 12, 20, Color::BLACK);
        }
    }

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

    На будущее: не пишите огромную портянку текста с кучей вопросов, а пишите только то что непосредственно относится к основному вопросу.
    Другие вопросы задавайте отдельно.
    Ответ написан
    Комментировать
  • Как запустить bat файл из кода Rust?

    vabka
    @vabka Куратор тега Rust
    std::process::Command
    Находится буквально по запросу: "rust start process"
    Ответ написан
    Комментировать