код макроса для rust

Пишем API на Rust с помощью процедурных макросов

Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в «закат солнца вручную», так как задачу приходится решать на очень низком уровне.

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

Предисловие

Прежде всего давайте определим задачу, которую мы будем решать с помощью макросов: мы попробуем определить некоторый абстрактный RPC API в виде трейта, который потом реализует как серверная часть, так и клиентская; а процедурные макросы, в свою очередь, помогут обойтись нам без кучи шаблонного кода. Несмотря на то, что реализовывать мы будем несколько абстрактный API, задача на самом деле довольно жизненная, и, помимо прочего, идеально подходит для демонстрации возможностей процедурных макросов.

Сам API у нас будет выполнен по очень простому принципу: есть 4 типа запросов:

Во всех случаях сервер будет отвечать валидным JSON объектом.

В идеале хочется получить нечто подобное:

Для начала напомню, что процедурными макросами в Rust’е называются специальные плагины к компилятору, которые получают на вход некоторое синтаксическое дерево, с которым производят некоторые манипуляции, а затем возвращают модифицированное дерево для последующей компиляции.
В рамках этой статьи мы будем рассматривать два вида таких макросов: derive-макросы, позволяющие автоматически реализовать трейт для какой-то структуры (многим они уже знакомы по serde ), и атрибутные макросы, которые можно использовать для большего спектра задач.

Создаем макрос FromUrlQuery

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

Итак, приступим. Для начала объявим наш трейт по разбору URL query. Данный трейт позволит нам получать из произвольной строки структуру данных, для которой этот трейт реализован. Выглядеть он будет так:

Чтобы иметь возможность автоматически реализовывать этот трейт, нам потребуется процедурный макрос. Данный макрос относится к типу макросов derive макросов и должен объявляться следующим образом:

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

В darling ‘е есть много вспомогательных макросов, но нас сейчас интересует только несколько из них.

Хочу отметить, что при этом если бы мы хотели знать, публичное это поле или нет, то могли бы изменить сигнатуру на следующую:

И все, на этом наш парсер готов.

Можно приступать к написанию кодогенератора.

А теперь посмотрим, как же будет в реальности выглядеть процесс кодогенерации FromUrlQuery :

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

Пишем макрос http_api

Код объявления атрибутных макросов несколько отличается и выглядит вот так:

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

Разбираем методы интерфейсного трейта

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

Объявим типы HTTP запросов, которые мы умеем обрабатывать:

И объявим набор атрибутов для метода, которые мы можем указывать:

Теперь можно переходить к разбору сигнатуры. Как я уже упоминал выше, нам нужно рассмотреть
два варианта — с дополнительным аргументом и без оного:

Разбираем интерфейсный трейт целиком

Теперь можно приступить к разбору трейта с интерфейсом в целом. Интерфейсный трейт всегда состоит исключительно из методов, разбор которых мы описали выше, а также дополнительных атрибутов.
Таким образом, мы можем разобрать его без особых сложностей:

Переходим к кодогенерации

Например, если мы хотим просто написать обработчик запросов, который на GET запрос будет просто возвращать некоторый JSON, то мы просто пишем что-то в таком стиле:

Для случая с GET запросами с параметрами мы лишь немного изменим обертку, которую мы написали выше, добавив еще один фильтр в цепочку:

Обработчики остальных двух типов запросов пишутся схожим образом.

Собираем обработчики воедино

А теперь с помощью комбинатора or собираем все фильтры воедино.

Заключение

С помощью этой статьи я хотел показать, что derive макросы не всегда так сложны в написании,
если использовать дополнительные библиотеки и следовать определенным практикам.
На мой взгляд, подобный подход к использованию трейтов наиболее удобен, если нужно описать
некоторый RPC, связывающий различные приложения, которые написаны на Rust’е.
Нетрудно заметить, что можно легко написать генератор реализации типажа-интерфейса для HTTP
клиентов типа reqwest и тем самым исключить возможность ошибиться в сопряжении клиента и сервера на корню.

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

Источник

Черная магия метапрограммирования: как работают макросы в Rust 1.15

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

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

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

Что можно почитать?

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

Поэтому большая часть актуальной документации представлена в электронном виде. Традиционным источником информации является Книга, в которой можно найти большинство ответов на вопросы новичков. Для совсем частых вопросов предусмотрен раздел FAQ.

Тем, кто уже имеет опыт программирования на других языках, и вообще достаточно взрослый, чтобы разбираться самостоятельно, подойдет другая книга. Предполагается, что она лучше подает материал и должна прийти на смену первой книге. А тем, кому нравится учиться на примерах, подойдет Rust by Example.

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

Если вас интересует история развития языка и взгляд с той стороны баррикад, крайне рекомендую блоги Aaron Turon и Niko Matsakis. Ребята пишут очень живым языком и рассказывают о текущих проблемах языка и о том, как предполагается их решать. Зачастую из этих блогов узнаешь куда больше актуальной информации, чем из других источников.

Наконец, если вы не боитесь драконов и темных углов, то можете взглянуть на Растономикон. Только предупреждаю, после прочтения этой книги вы уже не сможете смотреть на Rust прежним образом. Впрочем, я отвлекся…

Новое в Rust 1.15

С момента выпуска 1.14 прошло около 6 недель. За это время в новый релиз успели войти 1443 патча (неслабо, правда?) исправляющие баги и добавляющие новые возможности. А буквально на днях появился и хотфикс 1.15.1, с небольшими, но важными исправлениями.

За подробностями можно обратиться к странице анонса или к детальному описанию изменений (changelog). Здесь же мы сконцентрируемся на наиболее заметных изменениях.

Cargo уже взрослый

Cистема сборки компилятора и стандартной библиотеки Rust была переписана на сам Rust с использованием Cargo — стандартного пакетного менеджера и системы сборки, принятой в экосистеме Rust.

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

Уже даже завели уже вмержили pull request на удаление всех makefile; интеграция запланирована на релиз 1.17.

Все это готовит почву к прямому использованию пакетов из crates.io для сборки компилятора, как и в любом другом проекте. А еще это неплохая демонстрация возможностей Cargo.

Новые архитектуры

Более того, уже есть проекты использования Rust в embedded окружении. Разработчики компилятора опрашивают сообщество для выяснения потребностей этой пока малочисленной, но важной группы пользователей.

Быстрее! Выше! Сильнее!

Компилятор стал быстрее. А недавно еще и объявили о том, что система инкрементальной компиляции перешла в фазу бета-тестирования. На моих проектах время компиляции после незначительных изменений уменьшилось с

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

Алгоритм slice::sort() был переписан и стал намного, намного, намного быстрее. Теперь это гибридная сортировка, реализованная под влиянием Timsort. Раньше использовалась обычная сортировка слиянием.

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

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

Поддержка IDE

Этого пока нет в стабильном Rust, но тем не менее новость слишком значительная, чтобы о ней умолчать. Дело в том, что недавно разработчики Rust Language Server объявили о выходе альфа-версии своего детища.

Language Server Protocol это стандартный протокол, который позволяет редакторам и средам разработки общаться на одном языке с компиляторами. Он абстрагирует такие операции, как автодополнение ввода, переход к определению, рефакторинг, работу с буферами и т.д.

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

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

Макросы в Rust

Вернемся к нашим баранам.

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

Первый принцип больше соответствует традиционной декомпозиции программ: разделению кода на функции, методы, классы и т. п.

К второму можно отнести макросы, инклуды и прочий препроцессинг. В языке Rust для этого предусмотрено три механизма:

Обычные макросы (в документации macro by example) используются, когда хочется избежать повторения однообразного кода, но выделять его в функцию нерационально, либо невозможно. Макросы vec! или println! являются примерами таких макросов. Задаются декларативным образом. Работают по принципу сопоставления и подстановки по образцу. Реализация основана на базе работы 1986-го года, из которой они получили свое полное название.

Процедурные макросы являются первой попыткой стабилизации интерфейса плагинов компилятора. В отличие от обычных декларативных макросов, процедурные макросы представляют собой фрагмент кода на Rust, который выполняется в процессе компиляции программы и результатом работы которого является набор токенов. Эти токены компилятор будет интерпретировать как результат подстановки макроса.

Плагины компилятора являются самым мощным, но сложным и нестабильным (в смысле API) средством, которое доступно только в ночных сборках компилятора. В документации приведен пример плагина поддержки римских цифр в качестве числовых литералов.

Пример макроса

Поскольку макросы не ограничены лексическим контекстом функции, они могут генерировать определения и для более высокоуровневых сущностей. Например, макросом можно определить целый impl блок, или метод вместе с именем, списком параметров и типом возвращаемого значения.

Макро-вставки возможны практически во всех местах иерархии модуля:

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

Например, в стандартной бибилотеке Rust макросы используются для компактного объявления реализации типажа PartialEq для всевозможных сочетаний срезов, массивов и векторов:

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

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

Чистота и порядок

Макрос в Rust должен быть написан так, чтобы генерировать лексически корректный код. Это означает, что не всякий набор символов может быть валидным макросом. Это позволяет избежать многих проблем, связанных с использованием препроцессора в C/C++.

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

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

Корень зла лежит в том, что препроцессор C/C++ орудует на уровне текста, а компилятору приходится разбирать уже испорченную препроцессором программу.

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

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

Зато в пределах макроса можно заводить переменные, которые гарантировано не пересекутся с переменными выше по коду. Например, описанный выше макрос vec! можно переписать с использованием промежуточной переменной. Для простоты рассмотрим только основную ветвь:

после подстановки макроса будет преобразован в

Процедурные макросы

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

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

В качестве подопытного кролика возьмем реализацию автоматически выводимого конструктора #[derive(new)] из соответствующей библиотеки.

С точки зрения пользователя использование будет выглядеть так:

То есть, определив атрибут #[derive(new)] мы попросили компилятор самостоятельно вывести… а что именно? Откуда компилятор поймет, какой именно метод мы ожидаем получить? Давайте разбираться.

Для начала заглянем в исходный код библиотеки, к счастью он не такой большой:

А теперь разберем его по косточкам и попытаемся понять, что он делает.

Далее следует собственно функция, выступающая в роли точки входа в процедурный макрос:

На вход она получает набор токенов из компилятора, составляющих тело макроса. На выходе компилятор ожидает получить другой набор токенов, являющихся результатом применения макроса. Таким образом, функция derive() работает как своеобразный фильтр.

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

Итак, на вход нам могут подать:

Давайте посмотрим на код, генерирующий подстановку для обычной структуры. Здесь код дробить уже неудобно, поэтому я вставлю комментарии прямо в текст:

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

Сама структура еще раз:

Результат применения процедурного макроса:

Внезапно, все становится на свои места. Оказывается, мы только что собственноручно сгенерировали impl блок для структуры, добавили в него ассоциированную функцию-конструктор new() с документацией (!), двумя параметрами x и y соответствующих типов и с реализацией, которая возвращает нашу структуру, последовательно инициализируя ее поля значениями из своих параметров.

Поскольку Rust может понять из контекста, чему соответствуют x и y до и после двоеточия, все компилируется успешно.

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

Заключение

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

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

Материал подготовлен совместно с Дарьей Щетининой.

Источник

Rust: зачем нужны макросы

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

Где и как их уместно применять? Смотрите под катом.

Почему мы должны опасаться макросов

Макросы являются формой метапрограммирования: они являются кодом, который манипулирует кодом. Метапрограммирование получило плохую репутацию, потому что при их использовании нелегко уберечься от написания плохого кода. Примерами служат #define в C, который легко может взаимодействовать с кодом непредсказуемым образом, или eval в JavaScript, который увеличивают опасность инъекции кода.

О макросах в Rust

Многие их этих проблем могут быть решены при использовании необходимых средств, макросы же предоставляют некоторые такие средства:

Причиной того, что имеется два типа макросов является то, что они хорошо подходят для решения разных задач:

Почему функциональные макросы

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

Полезные утверждения

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

Типо-безопасная работа с форматом строк

Легкое логирование

В этом примере немного вдадимся в экосистему языка. Rust имеет пакет log, который используется как главный фронтенд логирования. Как и другие решения для логирования, он предоставляет разные уровни логирования, но, в отличие от других решений, данные уровни представляются макросами, а не функциями.

Логирование показывает мощность метапрограммирования в том, как оно использует макросы file! и line! ; Данные макросы дают возможность установить точное место расположения вызова функции логирования в исходном коде. Давайте посмотрим на пример. Так как log является фронтендом, добавим бэкенд, пакет flexi_logger.

Эта программа напечатает:

Как вы видите, наши логи содержат имена файлов и номера строк.

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

Если мы заменим логирующие макросы на функции, то по-прежнему можем вызывать file! и line! :

А данный код вывел бы следующее:

Почему атрибутные макросы

Rust включает в себя концепт атрибутов, который нужен для пометки кода. Например, функция тестирования выглядит так:

Запуск cargo test запустит данную функцию. Атрибутивные макросы позволяют вам создавать новые атрибуты, который подобны «родным» атрибутам, но имеют другие эффекты. На текущий момент существует важное ограничение: в компиляторе из ветки stable работают только макросы использующие атрибут derive, в то время как пользовательские атрибуты работают в ночных сборках. Рассмотрим разницу ниже.

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

Получение избыточного кода (boilerplate)

Derive с преимуществами

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

Наиболее выдающимся случаем использования на текущий момент является Rocket — библиотека для написания веб-серверов. Создание REST-endpoint’ов требует добавления атрибута к функции, так что теперь функция содержит всю необходимую информацию для обработки запроса.

Недостатки

Макросы не идеальны, рассмотрим их некоторые недостатки:

Выводы

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

Источник

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY).

код макроса для rust. eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. код макроса для rust фото. код макроса для rust-eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. картинка код макроса для rust. картинка eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. KoYQ Z7J3g R15HEr19zfSLxuKRhfQ Q4LvT53CukN5pbRJJgs7Md7axajCQH DqWbkvDfK0Zz1Q0oh1N6OFHYut. код макроса для rust фото. код макроса для rust-KoYQ Z7J3g R15HEr19zfSLxuKRhfQ Q4LvT53CukN5pbRJJgs7Md7axajCQH DqWbkvDfK0Zz1Q0oh1N6OFHYut. картинка код макроса для rust. картинка KoYQ Z7J3g R15HEr19zfSLxuKRhfQ Q4LvT53CukN5pbRJJgs7Md7axajCQH DqWbkvDfK0Zz1Q0oh1N6OFHYut. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

Стань лучшим в любимой игре, используй наши макросы на РАСТ и уничтожь своих врагов! У нас высококачественные макросы, которыми пользуются игроки со всего мира.

Проще купить макросы от «DEADXMACRO» для RUST и навсегда забыть про борьбу с отдачей. Наступила пора получать удовольствие от игры, вместо постоянного «горения пятой точки».

Есть вопросы? Обратись в личные сообщения группы, с любым интересующим вопросом, мы ответим максимально информативно!

код макроса для rust. 7zmzaZNKrE8. код макроса для rust фото. код макроса для rust-7zmzaZNKrE8. картинка код макроса для rust. картинка 7zmzaZNKrE8. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. WGuXqdzvgGE. код макроса для rust фото. код макроса для rust-WGuXqdzvgGE. картинка код макроса для rust. картинка WGuXqdzvgGE. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. CtRHpKtXg74. код макроса для rust фото. код макроса для rust-CtRHpKtXg74. картинка код макроса для rust. картинка CtRHpKtXg74. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. RHQQS82sr70. код макроса для rust фото. код макроса для rust-RHQQS82sr70. картинка код макроса для rust. картинка RHQQS82sr70. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. CymoHWZCHvc. код макроса для rust фото. код макроса для rust-CymoHWZCHvc. картинка код макроса для rust. картинка CymoHWZCHvc. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. ASuyqfXlHf4. код макроса для rust фото. код макроса для rust-ASuyqfXlHf4. картинка код макроса для rust. картинка ASuyqfXlHf4. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Еще одно дополнение предыдущих постов, связанных с Rust Twitch Drops. В недавнем посте от 4 сентября мы выпустили в продажу ограниченную партию аккаунтов Steam с полным набором скинов за очень небольшую для этого цену, и очень сильно удивились, когда увидели, сколько же людей хотят их приобрести, но с определенными «хотелками».

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

За подробностями обращайтесь в личные сообщения к Тимур Галиахметов

код макроса для rust. 61Uv569F92s. код макроса для rust фото. код макроса для rust-61Uv569F92s. картинка код макроса для rust. картинка 61Uv569F92s. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. 4rE2jsfwYXQ. код макроса для rust фото. код макроса для rust-4rE2jsfwYXQ. картинка код макроса для rust. картинка 4rE2jsfwYXQ. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. MjtXWPq12rY. код макроса для rust фото. код макроса для rust-MjtXWPq12rY. картинка код макроса для rust. картинка MjtXWPq12rY. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Исправили неточности кода в DELUXE версиях макросах для BLOODY!

Те кто ранее приобрел макросы, просим обратиться в личные сообщения сообщества с доказательством покупки и ID мышки, для получения исправленной версии макросов.

Наш интернет-магазин: https://deadxmacro.store (на сайте есть промокод).

С любовью команда DEADXMACRO.STORE код макроса для rust. e29da4. код макроса для rust фото. код макроса для rust-e29da4. картинка код макроса для rust. картинка e29da4. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Дополняем предыдущий пост. Выпускаем в продажу ограниченное количество аккаунтов Steam с игрой Rust со всеми скинами с первого по одиннадцатый раунд! Первая почта с письмом о регистрации аккаунта Steam в комплекте. На аккаунте никто и никогда не играл, не было заходов на классические и модифицированные сервера. Также на аккаунте было потрачено боле 5$, что означает доступность торговой площадки!

Аккаунт является личным, никаких рисков для Вас. Я могу гарантировать, что с аккаунтом 100% не будет никаких проблем, так как я лично регистрировал Steam аккаунты и получал на них предметы с раздач Rust Twitch Drops!

Пример Steam аккаунта, который Вы получите: https://vk.cc/c5A0uB

За подробностями обращайтесь в личные сообщения к Тимур Галиахметов

код макроса для rust. Rb4 H0 L0uagu0thEKI WMMZpKrD06YvR6PpqdxkciKjjK6zoZ1W1dlx9AH k Rt2IYAvnsBYpBCj8gVg54iLp3z. код макроса для rust фото. код макроса для rust-Rb4 H0 L0uagu0thEKI WMMZpKrD06YvR6PpqdxkciKjjK6zoZ1W1dlx9AH k Rt2IYAvnsBYpBCj8gVg54iLp3z. картинка код макроса для rust. картинка Rb4 H0 L0uagu0thEKI WMMZpKrD06YvR6PpqdxkciKjjK6zoZ1W1dlx9AH k Rt2IYAvnsBYpBCj8gVg54iLp3z. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. . код макроса для rust фото. код макроса для rust-. картинка код макроса для rust. картинка . Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. код макроса для rust фото. код макроса для rust-eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. картинка код макроса для rust. картинка eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

В продажу поступили аккаунты Rust Twitch Drops c одиннадцатым раундом. Для покупки новых и старых раундов, обращайтесь в ЛС к Тимур Галиахметов

Так же есть плохие новости для тех кто желал приобрести аккаунты Twitch со старыми раздачами. С началом 11-го раунда было технически запрещено получить скины с первого по восьмой раунд. В связи с чем было принято такое решение — неизвестно.

Возможно получить скины можно будет написав тикет в поддержку Facepunch.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Наконец-то стартовал новый раунд Rust Twitch Drops под номером 11! Раздача стартовала сегодня в 21:00 по МСК и продлятся до 9 сентября.

Список стримеров и их скины: ricoy23, blazed, silithur, elxokas, agustabell212, itsjewer, eltk, CNDBLOOD, kira, terpsicat.

код макроса для rust. ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. код макроса для rust фото. код макроса для rust-ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. картинка код макроса для rust. картинка ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

код макроса для rust. qU7aKz8bVIA1t6l4DvVFI6e8ktYbrrt0 MflYDrG0sH9CglnRvI20d4C5FjUdWt1ayX3Wl7HDkEPPv1WXJFCTByG. код макроса для rust фото. код макроса для rust-qU7aKz8bVIA1t6l4DvVFI6e8ktYbrrt0 MflYDrG0sH9CglnRvI20d4C5FjUdWt1ayX3Wl7HDkEPPv1WXJFCTByG. картинка код макроса для rust. картинка qU7aKz8bVIA1t6l4DvVFI6e8ktYbrrt0 MflYDrG0sH9CglnRvI20d4C5FjUdWt1ayX3Wl7HDkEPPv1WXJFCTByG. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. 1oyd2kVcFX qkbg JDNRlPhlXf8c88Rv8tXBUi OmeVjRuuZP8hATl HcNzi7LeTOVlXO4JpysC1YJnwwhmzO. код макроса для rust фото. код макроса для rust-1oyd2kVcFX qkbg JDNRlPhlXf8c88Rv8tXBUi OmeVjRuuZP8hATl HcNzi7LeTOVlXO4JpysC1YJnwwhmzO. картинка код макроса для rust. картинка 1oyd2kVcFX qkbg JDNRlPhlXf8c88Rv8tXBUi OmeVjRuuZP8hATl HcNzi7LeTOVlXO4JpysC1YJnwwhmzO. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. код макроса для rust фото. код макроса для rust-eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. картинка код макроса для rust. картинка eji9iYPSJobQNUEB5tTO2mK0fI eknX5Qeh 1 cAcqARxtu2j1ruC4ahQv 8f2GLkEwSKJlGVzQ8mPDgdveMISjS. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Просим извинения за задержку с результатами конкурса. Их почти вовремя можно было посмотреть в нашем фанчате, поэтому в виде списка мы их продублируем в данном посту.

На получение призов у победителей есть ровно сутки с момента выпуска этого поста. В случае недобора призов, будут произведены перевыборы!
Всем спасибо за участие. Выражаем благодарность Всем участникам конкурса!

код макроса для rust. ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. код макроса для rust фото. код макроса для rust-ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. картинка код макроса для rust. картинка ojOtCYGUDvWm3ix9hiLrZatvBxWCYg e3JauG5Qpg9vXKlEHQRHMS5aoaIgjw8OwVnFr2 adsJGWaPlX1NCc2V10. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. l63OCJV0COllk5zbHIvmymIbBFnUkEEZs w42yhBSLMZeCDR HWRP3iqPukc4eTZ01o NSfpPFkiZwOUnrTQQwG. код макроса для rust фото. код макроса для rust-l63OCJV0COllk5zbHIvmymIbBFnUkEEZs w42yhBSLMZeCDR HWRP3iqPukc4eTZ01o NSfpPFkiZwOUnrTQQwG. картинка код макроса для rust. картинка l63OCJV0COllk5zbHIvmymIbBFnUkEEZs w42yhBSLMZeCDR HWRP3iqPukc4eTZ01o NSfpPFkiZwOUnrTQQwG. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. qL7KPswHX2xKmXpoefM0CQuQuBmMedceW1bloTmWX OoXASYz 4Dhis36uOI57PwpmLA nEu0jD8jhsRUO Vzo4L. код макроса для rust фото. код макроса для rust-qL7KPswHX2xKmXpoefM0CQuQuBmMedceW1bloTmWX OoXASYz 4Dhis36uOI57PwpmLA nEu0jD8jhsRUO Vzo4L. картинка код макроса для rust. картинка qL7KPswHX2xKmXpoefM0CQuQuBmMedceW1bloTmWX OoXASYz 4Dhis36uOI57PwpmLA nEu0jD8jhsRUO Vzo4L. Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. . код макроса для rust фото. код макроса для rust-. картинка код макроса для rust. картинка . Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

код макроса для rust. . код макроса для rust фото. код макроса для rust-. картинка код макроса для rust. картинка . Тем не менее, многие вполне обоснованно побаиваются пользоваться этим инструментом, в основном из-за того, что разбор синтаксического дерева и атрибутов макроса зачастую превращается в "закат солнца вручную", так как задачу приходится решать на очень низком уровне.

DXM | Макросы на РАСТ (LOGITECH, RAZER, BLOODY). запись закреплена

Здравия желаем! Вот и настал тот час, когда мы можем поговорить про новые сборки Windows 10, и макросы для них.

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

Сегодняшний день можно считать как новую страницу в истории скриптинга. Но на данный момент это всё, чем мы хотели бы поделиться с Вами. Спасибо, что выбираете именно нас. Всех благ!

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *