Size: a a a

Rust — русскоговорящее сообществo

2020 September 28

V

Vladimir in Rust — русскоговорящее сообществo
Раньше в плагинах компилятора была апишка для разворачивания внутренних макросов. Скорее всего в текущих процедурных макросах этого нет, так как они не имеют в своем контексте ничего кроме того что идёт аргументом.

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

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Vladimir
Раньше в плагинах компилятора была апишка для разворачивания внутренних макросов. Скорее всего в текущих процедурных макросах этого нет, так как они не имеют в своем контексте ничего кроме того что идёт аргументом.

А что ты хотел сделать, для чего тебе было важно чтоб внутренний макрос выполнился раньше?
У меня есть "асинхронный трейт" через процедурный макрос
#[async_trait]
impl BucketAdapter for Adapter {
}

И есть одна из его имплементаций, которая использует так называемый enum-dispatch. Т.е. это имплементация для enum-а, который содержит в себе "структуры", которые тоже имплементят этот трейт. И все реализации методов трейта для этого энума выглядят однообразно:
match self {
  T1(adapter) => adapter.method(arg1, arg2).await,
  T2(adapter) => adapter.method(arg1, arg2).await,
}

Я хотел декларативным макросом генерить эти методы только по одной их декларации. Но из-за этого макрос async_trait не видит эти методы, и потому не делает свою магию, подменяя async fn на обычный fn.
источник

Э

Эрик in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
У меня есть "асинхронный трейт" через процедурный макрос
#[async_trait]
impl BucketAdapter for Adapter {
}

И есть одна из его имплементаций, которая использует так называемый enum-dispatch. Т.е. это имплементация для enum-а, который содержит в себе "структуры", которые тоже имплементят этот трейт. И все реализации методов трейта для этого энума выглядят однообразно:
match self {
  T1(adapter) => adapter.method(arg1, arg2).await,
  T2(adapter) => adapter.method(arg1, arg2).await,
}

Я хотел декларативным макросом генерить эти методы только по одной их декларации. Но из-за этого макрос async_trait не видит эти методы, и потому не делает свою магию, подменяя async fn на обычный fn.
Можешь руками развернуть определение функции.
источник

Э

Эрик in Rust — русскоговорящее сообществo
А вообще, зачем тебе его разворачивать?
источник

Э

Эрик in Rust — русскоговорящее сообществo
У тебя же enum-dispatch сам должен поймать трейт и развернуться как надо, нет?
источник

Э

Эрик in Rust — русскоговорящее сообществo
В смысле, зачем await на футуру в имплементации на enum, если там всё равно возвращается Box<dyn Future>?
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Эрик
В смысле, зачем await на футуру в имплементации на enum, если там всё равно возвращается Box<dyn Future>?
Что бы не писать громоздкую декларацию метода (особенно тип результата). Хотя если генерить это макросом, то может и ничего так будет.
источник

Э

Эрик in Rust — русскоговорящее сообществo
Kirill (Cykooz) Kuzminykh
Что бы не писать громоздкую декларацию метода (особенно тип результата). Хотя если генерить это макросом, то может и ничего так будет.
А какая разница, если у тебя возвращённое из трейта отличается только лайфтаймом?
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Эрик
Можешь руками развернуть определение функции.
На самом деле там не так всё просто, как в этом примере где у метода даже нет аргументов. Вот в такую кашу разворачивается метод с одним аргументом-ссылкой.
Было:
async fn get_file_content(&self, name: &str) -> Result<ByteStream, StorageError>;
Развернулось в:
#[must_use]
fn get_file_content<'life0, 'life1, 'async_trait>(
   &'life0 self,
   name: &'life1 str,
) -> ::core::pin::Pin<
   Box<
       dyn ::core::future::Future<Output = Result<ByteStream, StorageError>>
       + ::core::marker::Send
       + 'async_trait,
   >,
>
   where
       'life0: 'async_trait,
       'life1: 'async_trait,
       Self: 'async_trait;
Я наверное убъюсь делать такое развёртывание самостоятельно в декларативном макросе
источник

KK

Kirill (Cykooz) Kuzm... in Rust — русскоговорящее сообществo
Не стоит шкурка выделки ради одного асинхронного трейта которому понадобилась enum-dispatch имплементация. Проще руками её запилить.
источник
2020 September 29

𝛈µ

𝛈 µ in Rust — русскоговорящее сообществo
Denis
какая тебе разница, как конкретно оно сериализует?
Мне не хочется, чтобы юзер ебался с редактированием жутко неудобной формы томла
источник

𝛈µ

𝛈 µ in Rust — русскоговорящее сообществo
Vladimir
+ Можешь же патч создать, чтоб было как ты хочешь)
Не могу, я растодебил
источник

IG

Igor Gulamov in Rust — русскоговорящее сообществo
Mikail Bagishov
По-моему ОП (https://t.me/rustlang_ru/332695) нужна просто мапа, которая умеет в next_key и prev_key, и получится вполне себе разреженный массив
как-то так. Правда, реализации именно таких векторов наверняка имеют оптимизации, связанные с тем, что размерность у них не очень большая (т е не обязательно делать hashmap, patricia tree тоже норм)

большинство sparse векторов в crates.io - это просто Vec<(K,V)>. Очень неоптимальная конструкция.
источник

MF

Max Frai in Rust — русскоговорящее сообществo
Как в actix-web запустить в потоке асинхронную функцию?
источник

MF

Max Frai in Rust — русскоговорящее сообществo
#[actix_web::main]
async fn main() {

Внутри где-то там запускается actix-web сервер, но до этого нужно сделать thread::spawn, где внутри вызывается асинхронная функци
источник

IL

Ilya Lakhin in Rust — русскоговорящее сообществo
Привет!

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

Делаю я это так. Я объявил публичный модуль, и в нем объявил публичный трейт A<T>. И затем в этом модуле объявил еще приватный подмодуль, в котором объявил публичный трейт B<T>. Причем A наследует B: A<T>: B<T>. Ну и там разных методов объявил и в том, и в другом.

И затем в крейте объявил публичную структуру S и заимплементил от нее A<X> и B<X>, где X - некая приватная структура внутри крейта(которая не является частью темплейт-сигнатуры структуры S). И все это отлично работает внутри крейта. Но снаружи у меня неполучается вызывать методы A<X> моей структуры S. Он говорит, что эти методы используют приватную X, хотя она в явном виде не присутствует ни в методах A, ни в сигнатуре S
источник

IL

Ilya Lakhin in Rust — русскоговорящее сообществo
Вот, скажем, пример метода в трейте A:

    #[inline]
   fn clear(&mut self) {
       *self.inner_mut() = Default::default();
   }


(это дефолтная имплементация, которую я использую вовне крейта)
источник

IL

Ilya Lakhin in Rust — русскоговорящее сообществo
Хотя проблема здесь наверное не в приватных методах, а в том, что X приватный. Как это можно обойти?
источник

JG

JeisonWi Garrison in Rust — русскоговорящее сообществo
источник

JG

JeisonWi Garrison in Rust — русскоговорящее сообществo
источник