<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
    <title>Блог Бишонена - Rust</title>
    <subtitle>Ещё один блог о разработке программного обеспечения.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bshn.rs/ru/categories/rust/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bshn.rs"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-04-21T00:00:00+00:00</updated>
    <id>https://bshn.rs/ru/categories/rust/atom.xml</id>
    <entry xml:lang="ru">
        <title>Не столь тривиальные приведения типов</title>
        <published>2026-04-21T00:00:00+00:00</published>
        <updated>2026-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            Nikita Bishonen
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/not-so-trivial-casts/"/>
        <id>https://bshn.rs/ru/blog/not-so-trivial-casts/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/not-so-trivial-casts/">&lt;h1 id=&quot;ne-stol-trivial-nye-privedeniia-tipov&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ne-stol-trivial-nye-privedeniia-tipov&quot; aria-label=&quot;Anchor link for: ne-stol-trivial-nye-privedeniia-tipov&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Не столь тривиальные приведения типов&lt;&#x2F;h1&gt;
&lt;p&gt;В Rust существует интересный lint под названием &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;nightly-rustc&#x2F;rustc_lint&#x2F;builtin&#x2F;static.TRIVIAL_CASTS.html&quot;&gt;&lt;code&gt;trivial_casts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
который оказывается не таким уж тривиальным.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It may be possible that this will become a warning in the future&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;поэтому давайте рассмотрим несколько примеров кода, где я буду сравнивать:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Тривиальные приведения типов&lt;&#x2F;li&gt;
&lt;li&gt;Определения типов переменных&lt;&#x2F;li&gt;
&lt;li&gt;Неявное приведение типа&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Я не буду добавлять никаких комментариев, кроме вывода компилятора, чтобы вы могли увидеть разницу самостоятельно и решить,
когда и как использовать приведение типов в коде Rust. Я только скажу, что &lt;code&gt;trivial_cast_supertype_with_shadowing&lt;&#x2F;code&gt; похоже
является хорошим примером того, как &lt;strong&gt;trivial_casts&lt;&#x2F;strong&gt; могут стать не столь тривиальными даже в небольшом примере (представьте,
что может произойти в более длинной цепочке вызовов и преобразований&#x2F;приведений типов).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;dead_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;warn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;trivial_casts&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #565869);&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #565869);&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; tests&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    use&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; crate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; explicit_definition_supertype&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square); expected &amp;amp;Square, found &amp;amp;(dyn Polygon + &amp;#39;static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; explicit_definition_subtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square); expected &amp;amp;Square, found &amp;amp;(dyn TwoSidedPolygon + &amp;#39;static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; trivial_cast_supertype&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; trivial cast: `&amp;amp;Square` as `&amp;amp;dyn Polygon`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square); expected &amp;amp;Square, found &amp;amp;dyn Polygon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; trivial_cast_subtype&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; trivial cast: `&amp;amp;Square` as `&amp;amp;dyn TwoSidedPolygon` &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square); expected &amp;amp;Square, found &amp;amp;(dyn TwoSidedPolygon + &amp;#39;static)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; trivial_cast_struct_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; trivial cast: `&amp;amp;Square` as `&amp;amp;Square`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process_square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; auto_coercion&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process_square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; shadowed_auto_coercion&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process3(square); the trait bound `Triangle: TwoSidedPolygon` is not satisfied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square); expected &amp;amp;Square, found &amp;amp;Triangle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process_triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; trivial_cast_supertype_with_shadowing&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;dyn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; trivial cast: `&amp;amp;Square` as `&amp;amp;Square`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; process_square(square);  expected &amp;amp;Square, found &amp;amp;dyn Polygon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; process_square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;_square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Square&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; process_triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;_triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Triangle&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;_polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Sized&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; process2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;_polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; process3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;_polygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; TwoSidedPolygon&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Sized&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Безопасность отмены в разных Rust Async-рантаймах</title>
        <published>2026-04-01T00:00:00+00:00</published>
        <updated>2026-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            Никита Бишонен
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/"/>
        <id>https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/2026-04-01-cancellation-safety-in-async-rust-runtimes/">&lt;p&gt;Для более глубокого понимания я рекомендую своим дорогим друзьям прочитать или посмотреть отличный &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sunshowers.io&#x2F;posts&#x2F;cancelling-async-rust&#x2F;&quot;&gt;тред&lt;&#x2F;a&gt;, сделанный Рейном,
где она описывает её отношение к “безопасности отмены” в Rust с асинхронностью.&lt;&#x2F;p&gt;
&lt;p&gt;TL;DR для тех, кто предпочитает хакать, а не читать:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git clone https:&#x2F;&#x2F;gitlab.com&#x2F;blogging1&#x2F;cancellation-safety&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cargo test --no-fail-fast --workspace&lt;&#x2F;code&gt; (или ваш рантайм по выбору с &lt;code&gt;-p cancel_%RUNTIME%&lt;&#x2F;code&gt; вместо &lt;code&gt;--workspace&lt;&#x2F;code&gt;);&lt;&#x2F;li&gt;
&lt;li&gt;Читайте ошибки и тесты;&lt;&#x2F;li&gt;
&lt;li&gt;Читайте &lt;code&gt;lib.rs&lt;&#x2F;code&gt; для рантаймов, которые вас интересуют;&lt;&#x2F;li&gt;
&lt;li&gt;Играйте с кодом, чтобы исправить все тесты.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;problema&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#problema&quot; aria-label=&quot;Anchor link for: problema&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Проблема&lt;&#x2F;h1&gt;
&lt;p&gt;“Безопасность отмены” обычно означает отсутствие неожиданных “эффектов”, когда последовательность асинхронных операций прерывается до того, как она достигнет финального состояния.
Я могу представить &lt;code&gt;panic!&lt;&#x2F;code&gt; посередине синхронной последовательности операций как аналогию.&lt;&#x2F;p&gt;
&lt;p&gt;Её фундаментальные принципы связаны с трейтом &lt;code&gt;Future&lt;&#x2F;code&gt; и деталями реализации асинхронного рантайма.
Здесь я хотел бы провести эксперимент, чтобы найти общие паттерны и различия в том, как Tokio, smol и glommio обрабатывают отмены.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Future::poll&lt;&#x2F;code&gt; — ключевой аспект здесь, так как на этапе компиляции каждая реализация &lt;code&gt;Future&lt;&#x2F;code&gt; представляет собой конечный автомат,
представляющий последовательность операций, “отмена” означает, что &lt;strong&gt;Runtime&lt;&#x2F;strong&gt; (Реактор, Event Loop или планировщик) перестанет опрашивать этот конечный автомат и (надеюсь) уничтожит его состояние;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Pin&lt;&#x2F;code&gt; и &lt;code&gt;Unpin&lt;&#x2F;code&gt; имеют свои места, так как типы &lt;code&gt;!Unpin&lt;&#x2F;code&gt; должны обеспечивать дополнительные гарантии, чтобы считаться “безопасными” (снижение “эффектов”);&lt;&#x2F;li&gt;
&lt;li&gt;Реализация &lt;code&gt;Waker&lt;&#x2F;code&gt; может играть большую роль в обработке запросов об отмене.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;primer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#primer&quot; aria-label=&quot;Anchor link for: primer&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Пример&lt;&#x2F;h1&gt;
&lt;p&gt;В нашем приключении мы присоединимся к нашим сильным и гордым друзьям, живущим в Мории:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;MAX_ALLOWED_SHIFTS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;        println!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;Здесь у ворот король ОЖИДАЕТ&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;так наш асинхронный процесс будет имитировать работу гнома в шахтах. Сам &lt;code&gt;mine_with_tool&lt;&#x2F;code&gt; является композитной реализацией &lt;code&gt;trait Future&lt;&#x2F;code&gt;,
внутри которой выполняется &lt;code&gt;MAX_ALLOWED_SHIFTS&lt;&#x2F;code&gt; шагов для достижения своего финального (завершенного) состояния.
Простыми словами, строка 4: &lt;code&gt;pickaxe().await;&lt;&#x2F;code&gt; будет точкой, где конечный автомат опрашивается и продвигается вперед.
Это означает, что именно в этом месте может быть использовано для “отмены” выполнения.&lt;&#x2F;p&gt;
&lt;p&gt;Как это выглядит на высокоуровневом промежуточном представлении (код очищен для большей лаконичности, пожалуйста, запустите &lt;code&gt;cargo +nightly rustc -- -Z unpretty=hir&lt;&#x2F;code&gt;
внутри папки &lt;code&gt;moria&lt;&#x2F;code&gt;, чтобы увидеть полный вывод):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #565869);font-style: italic;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; &#x2F;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;impl Trait&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    where&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; FnMut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt; FT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; _task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; ResumeTy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; next&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;                None&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; break&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;                Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                    match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; into_future&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;pickaxe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                        mut&lt;&#x2F;span&gt;&lt;span&gt; __awaitee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                            loop&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                                match&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; unsafe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;                                        poll&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new_unchecked&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; __awaitee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;                                            get_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;_task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                                    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;                                    Ready&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;  0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; break&lt;&#x2F;span&gt;&lt;span&gt; result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;                                    Pending&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                _task_context&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;yield&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                            }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;                    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;почти никакой “async” магии больше, у нас есть &lt;code&gt;loop&lt;&#x2F;code&gt;, &lt;code&gt;unsafe&lt;&#x2F;code&gt; и &lt;code&gt;yield ()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Давайте перейдем к “безопасности”. По моему скромному мнению, если нет &lt;code&gt;unsafe&lt;&#x2F;code&gt; кода и компилятор Rust доволен, операция безопасна.
Однако это не означает, что программа ведет себя так, как ожидают от неё программисты.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; mine_with_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ferrum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dirty&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;попробуйте сами понять, что делает эту реализацию &lt;code&gt;trait Future&lt;&#x2F;code&gt; названной “небезопасной отменой” (я предпочитаю небезопасная, так как &lt;strong&gt;unsafe&lt;&#x2F;strong&gt;
важно, но является отдельным термином Rust).&lt;&#x2F;p&gt;
&lt;p&gt;Ответ кроется в том, как эта асинхронная операция хранит свое состояние и отслеживает свой прогресс. Обе эти вещи происходят внутренне,
при этом удерживая изменяемую ссылку на состояние, предоставляемую вызывающей стороной &lt;code&gt;dwarf: &amp;amp;mut Dwarf&lt;&#x2F;code&gt;.
Давайте посмотрим на два примера использования этой функции внутри рантайма &lt;code&gt;smol&lt;&#x2F;code&gt;, чтобы понять, почему такая реализация может давать сюрпризы вызывающей стороне,
если произойдет отмена.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;mine&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;or&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;            Timer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;after&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;HALF_SHIFT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Гном здесь работает половину смены времени и сделал некоторый прогресс.
Но когда мы идем смотреть, как запускается тест:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dwalin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Сумка пуста, но я слышал песню!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;assert!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dwallin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;is_some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;мы видим, что проверка того, что работа была проделана, не проходит.
Причина в том, что таймаут наступил до того, как Двалину удалось завершить свою работу, и всё, что он положил в “сумку”
во внутреннем состоянии конечного автомата, было отброшено, как только мы отменили операцию в первом опросе после таймаута.
(Попробуйте изменить &lt;code&gt;Timer::after(HALF_SHIFT)&lt;&#x2F;code&gt; на использование &lt;code&gt;FULL_SHIFT&lt;&#x2F;code&gt; и посмотрите, поможет ли это 😉).
Так это то, что мы можем назвать небезопасной отменой (или некорректной, как предложила Рейн) реализацией асинхронной операции,
которая приводит к поведению, которого мы не ожидаем.&lt;&#x2F;p&gt;
&lt;p&gt;Более интересный (и более близкий к реальности) сценарий может произойти, если сделать нашу реализацию &lt;code&gt;Future&lt;&#x2F;code&gt; более сложной и “грязной”:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; work&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Mutex&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;lock&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; old_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;HALF_SHIFT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;mine&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;err&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;new_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; dwarf_guard&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;as_mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        new_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; old_bag&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Я знаю, гномы не любят асинхронное программание, но это иллюстрирует проблему очень хорошо.
Наша операция извлекает состояние из входных данных, держит его внутренне, затем накапливает с собственными результатами вычислений и возвращает его обратно.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;┌────────────────────────────────────────────────────────────────────────────────────────┐&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  ┌────────────┐    ┌──────────────┐    ┌───────┐    ┌─────────────┐    ┌──────────────┐│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  │ Lock Mutex │ -&amp;gt; │ Take Old Bag │ -&amp;gt; │ Mine  │ -&amp;gt; │Take New Bag │ -&amp;gt; │  Merge Bags  ││&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  └────────────┘    └──────────────┘    └───────┘    └─────────────┘    └──────────────┘│&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  ┌────────────┐    ┌──────────────┐                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│-&amp;gt;│Release Lock│ -&amp;gt; │    End       │                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  └────────────┘    └──────────────┘                                                    │&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└────────────────────────────────────────────────────────────────────────────────────────┘&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Проблема в том, что с точки зрения мьютекса операция “безопасна”, так как мы знаем, что никто больше не изменит состояние &lt;code&gt;dwarf&lt;&#x2F;code&gt;.
Однако она “некорректна”, если мы отменим &lt;code&gt;super::mine&lt;&#x2F;code&gt; до того, как она полностью завершится.
&lt;code&gt;old_bag&lt;&#x2F;code&gt; будет отброшен, так как &lt;code&gt;new_bag&lt;&#x2F;code&gt; не будет существовать (&lt;code&gt;dwarf_guard.bag.as_mut()&lt;&#x2F;code&gt; равно &lt;code&gt;None&lt;&#x2F;code&gt;).
Так как реализация будущего &lt;code&gt;work&lt;&#x2F;code&gt; является композицией самой себя с реализацией будущего &lt;code&gt;super::mine&lt;&#x2F;code&gt; и реализацией будущего &lt;code&gt;timeout&lt;&#x2F;code&gt;,
наша логика ломается, так как оба будущего ведут себя некорректно с точки зрения системы (хотя это полностью ожидаемо, валидно и &lt;strong&gt;безопасно&lt;&#x2F;strong&gt; Rust-код по моему мнению).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sravnenie&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sravnenie&quot; aria-label=&quot;Anchor link for: sravnenie&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Сравнение&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;obzor-arkhitektury-rantaima&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#obzor-arkhitektury-rantaima&quot; aria-label=&quot;Anchor link for: obzor-arkhitektury-rantaima&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Обзор архитектуры рантайма&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tokio-otraslevoi-standart&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tokio-otraslevoi-standart&quot; aria-label=&quot;Anchor link for: tokio-otraslevoi-standart&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Tokio: Отраслевой стандарт&lt;&#x2F;h3&gt;
&lt;p&gt;Tokio представляет собой самый широко используемый асинхронный рантайм в экосистеме Rust.
Его архитектура фокусируется на:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Многопоточный пул исполнителей&lt;&#x2F;strong&gt; для вычислительно-тяжелых задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Модель завершения на основе Completer&lt;&#x2F;strong&gt; для неблокирующих операций;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Надежная отмена задач&lt;&#x2F;strong&gt; с явными возможностями прерывания;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Комплексная экосистема&lt;&#x2F;strong&gt; поддерживающих библиотек;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Встроенные токены отмены через &lt;code&gt;tokio_util::sync::CancellationToken&lt;&#x2F;code&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokio::spawn()&lt;&#x2F;code&gt; для создания задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tokio::select!&lt;&#x2F;code&gt; для одновременных операций;&lt;&#x2F;li&gt;
&lt;li&gt;Встроенные утилиты таймаута;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;smol-minimalistichnyi-podkhod&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#smol-minimalistichnyi-podkhod&quot; aria-label=&quot;Anchor link for: smol-minimalistichnyi-podkhod&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
smol: Минималистичный подход&lt;&#x2F;h3&gt;
&lt;p&gt;smol использует радикально другой подход с:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Однопоточный исполнитель&lt;&#x2F;strong&gt; по умолчанию;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Упрощенный API&lt;&#x2F;strong&gt;, фокусирующийся на основных асинхронных операциях;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Собственного рантайма нет&lt;&#x2F;strong&gt; — он предоставляет существующие исполнители;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Легковесные зависимости&lt;&#x2F;strong&gt; и минимальные накладные расходы;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;smol::spawn()&lt;&#x2F;code&gt; для создания задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;smol::Timer&lt;&#x2F;code&gt; для асинхронных задержек;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;smol::channel&lt;&#x2F;code&gt; для передачи сообщений;&lt;&#x2F;li&gt;
&lt;li&gt;Нет явных токенов отмены в основном API;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;glommio-fokus-na-proizvoditel-nosti-i-o&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#glommio-fokus-na-proizvoditel-nosti-i-o&quot; aria-label=&quot;Anchor link for: glommio-fokus-na-proizvoditel-nosti-i-o&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Glommio: Фокус на производительности I&#x2F;O&lt;&#x2F;h3&gt;
&lt;p&gt;Glommio представляет собой специализированный рантайм, разработанный для высокопроизводительных нагрузок I&#x2F;O:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Локальная модель исполнителя&lt;&#x2F;strong&gt; с подходом “share-nothing-first”;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Оптимизированный для I&#x2F;O&lt;&#x2F;strong&gt; с архитектурой thread-per-core;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Нет общей памяти&lt;&#x2F;strong&gt; между потоками по умолчанию;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Локальные только futures&lt;&#x2F;strong&gt; для лучшей локальности кэша;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Ключевые характеристики:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;glommio::LocalExecutor&lt;&#x2F;code&gt; для однопоточного выполнения;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::spawn_local()&lt;&#x2F;code&gt; для задач;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::timer&lt;&#x2F;code&gt; для задержек;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;glommio::channels::local_channel&lt;&#x2F;code&gt; для локальной только коммуникации;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;analiz-stsenariev-otmeny&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#analiz-stsenariev-otmeny&quot; aria-label=&quot;Anchor link for: analiz-stsenariev-otmeny&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Анализ сценариев отмены&lt;&#x2F;h2&gt;
&lt;p&gt;Большинство сценариев ведут себя похоже в разных рантаймах:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Простая отмена через Drop: используйте явные механизмы drop для futures, и все рантаймы показывают частичную потерю работы, когда futures отбрасываются неожиданно;&lt;&#x2F;li&gt;
&lt;li&gt;Отмена через таймаут: все предоставляют явную обработку таймаута, и тесты показывают, что таймаут не сохраняет частичные результаты;&lt;&#x2F;li&gt;
&lt;li&gt;Операции, защищенные мьютексом: &lt;code&gt;tokio::sync::Mutex&lt;&#x2F;code&gt;, &lt;code&gt;smol::lock::Mutex&lt;&#x2F;code&gt;, &lt;code&gt;glommio::sync::RwLock&lt;&#x2F;code&gt; имеют схожую семантику,
в то время как тесты демонстрируют паттерны удержания блокировок и очистка работает так, как должно, хотя мы все равно теряем прогресс;&lt;&#x2F;li&gt;
&lt;li&gt;Коммуникация на основе каналов: очень похоже, только с нюансами локальности;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Но некоторые из них имеют нюансы:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Макросы вроде &lt;code&gt;select!&lt;&#x2F;code&gt; и одновременные операции с токенами отмены специфичны для экосистемы рантайма &lt;code&gt;Tokio&lt;&#x2F;code&gt;,
что кажется не хорошим или плохим делом. Как описала Рейн в своём треде и что я слышал от других разработчиков,
такие макросы иногда полностью запрещаются в проектах из-за их неявного характера (и например заменяются на &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;futures-concurrency&#x2F;latest&#x2F;futures_concurrency&#x2F;&quot;&gt;futures_concurrency&lt;&#x2F;a&gt;);&lt;&#x2F;li&gt;
&lt;li&gt;“Явная” отмена:
&lt;ul&gt;
&lt;li&gt;в &lt;code&gt;Tokio&lt;&#x2F;code&gt; делается через &lt;code&gt;JoinHandle::abort&lt;&#x2F;code&gt;, и отбрасывание хендла не вызывает отмену, &lt;code&gt;nahdle.await&lt;&#x2F;code&gt; вернет ошибку &lt;code&gt;JoinError&lt;&#x2F;code&gt;
если реализация будущего была отменена (или нормальный результат, если она завершилась), также стоит отметить, что задачи &lt;code&gt;spawn_blocking&lt;&#x2F;code&gt; не являются “отменяемыми”,
так как они не асинхронны (но это предотвратит запуск задачи, если она еще не началась!);&lt;&#x2F;li&gt;
&lt;li&gt;в &lt;code&gt;smol&lt;&#x2F;code&gt; можно вызвать &lt;code&gt;Task::cancel&lt;&#x2F;code&gt; и дождаться отмены (которая может вернуть &lt;code&gt;Some&lt;&#x2F;code&gt;, если завершилась), это похоже на отбрасывание реализации будущего;&lt;&#x2F;li&gt;
&lt;li&gt;в &lt;code&gt;glommio&lt;&#x2F;code&gt; подход также идентичен &lt;code&gt;smol&lt;&#x2F;code&gt; с тем, что возвращается &lt;code&gt;Option&lt;&#x2F;code&gt; при ожидании отмены;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Со стороны документации эта тема покрыта только в документации API &lt;code&gt;Tokio&lt;&#x2F;code&gt;, &lt;code&gt;smol&lt;&#x2F;code&gt; имеет одну маленькую (ха-ха) заметку на этот счет:&lt;strong&gt;Примечание, что отмена задачи на самом деле разбудит её и перепланирует в последний раз. Затем исполнитель может уничтожить задачу, просто отбросив её Runnable или вызвав run().&lt;&#x2F;strong&gt;,
в то время как в &lt;code&gt;glommio&lt;&#x2F;code&gt; я не смог найти упоминаний о безопасности отмены или корректности. Я думаю, есть два фактора, почему это так:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;У Tokio гораздо большая популярность и использование, хотя и больше ресурсов для добавления документации;&lt;&#x2F;li&gt;
&lt;li&gt;У Tokio гораздо более “опасный” API и внутренняя модель исполнителя, что делает его легче встретить проблемы безопасности отмены при его использовании;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Надеюсь, вы нашли что-то новое в этом блог-посте, пишите свои мысли в комментариях и проверьте дополнительные ресурсы, если хотите.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot; aria-label=&quot;Anchor link for: dopolnitel-nye-resursy-i-istochniki-vdokhnoveniia&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Дополнительные ресурсы и источники вдохновения&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Отличный тред Рейна &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sunshowers.io&#x2F;posts&#x2F;cancelling-async-rust&#x2F;&quot;&gt;talk&lt;&#x2F;a&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;Текущий комментарий о &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;async-book&#x2F;issues&#x2F;227#issuecomment-2496234560&quot;&gt;state of the book section&lt;&#x2F;a&gt; о безопасности отмены;&lt;&#x2F;li&gt;
&lt;li&gt;Документация Tokio на &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;tokio&#x2F;latest&#x2F;tokio&#x2F;sync&#x2F;mpsc&#x2F;struct.Sender.html#cancel-safety&quot;&gt;эту тему&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;futures-concurrency&#x2F;latest&#x2F;futures_concurrency&#x2F;&quot;&gt;Structured Concurrency lib&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(Конец файла - всего 266 строк)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Rust Types - Taxonomy</title>
        <published>2025-02-19T00:00:00+00:00</published>
        <updated>2025-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            Nikita Bishonen
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/2025-02-19-rust-types-taxonomy/"/>
        <id>https://bshn.rs/ru/blog/2025-02-19-rust-types-taxonomy/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/2025-02-19-rust-types-taxonomy/">&lt;p&gt;Привет! Сегодня я делюсь своими мыслями о таксономии типов в Раст. Это первая версия таксономии и поста, буду благодарен за любые идеи по её улучшению.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;taksonomiia&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#taksonomiia&quot; aria-label=&quot;Anchor link for: taksonomiia&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Таксономия&lt;&#x2F;h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Таксоно́мия&lt;&#x2F;strong&gt; (от др.-греч. τάξις — строй, порядок и νόμος — закон) — учение о принципах и практике классификации и систематизации сложноорганизованных иерархически соотносящихся сущностей.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Я захотел украсить свой кабинет графической иллюстрацией “таксономии” системы типов данных, схожей с той, что использует Раст. К сожалению мои поиски не принесли желаемый результат и я решил сделать свою иллюстрацию и делюсь ею с вами в этой публикации.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tipy&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tipy&quot; aria-label=&quot;Anchor link for: tipy&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Типы&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;teorii&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#teorii&quot; aria-label=&quot;Anchor link for: teorii&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Теории&lt;&#x2F;h2&gt;
&lt;p&gt;Теорий существует множество, некоторые из которых обусловлены историей развития науки о вычислениях, другие имеют действительную практическую ценность и теоретическое обоснование. Приведу ссылки на две популярные теории из обеих категорий:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Intuitionistic_type_theory&quot;&gt;Intuitionistic type theory&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ryansandford.github.io&#x2F;projects&#x2F;hott&#x2F;&quot;&gt;Homotopy Type Theory&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Но не буду пытаться вдаваться в детали, поскольку понимаю их со скрипом, что уж говорить о способности их объяснить.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025_02_19_tax_hott.png&quot; alt=&quot;HoTT&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#&quot; aria-label=&quot;Anchor link for: &quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Теории типов и Раст&lt;&#x2F;h2&gt;
&lt;p&gt;Собственно основным вопросом, ответ на который я искал - теория типов стоящая за Раст и её проекция на типы, которые мы используем при написании кода на Раст.
Не я один задавался таким вопросом: https:&#x2F;&#x2F;users.rust-lang.org&#x2F;t&#x2F;practical-intro-to-type-theory&#x2F;18204&#x2F;5
Также есть небольшой доклад на эту тему: https:&#x2F;&#x2F;av.tib.eu&#x2F;media&#x2F;52178
“Ментальная модель”: https:&#x2F;&#x2F;ia0.github.io&#x2F;unsafe-mental-model&#x2F;type-theory.html
А также интересный пост: https:&#x2F;&#x2F;www.kurtlawrence.info&#x2F;blog&#x2F;category-theory-with-rust-pt1
Но все они имеют много букв и не имеют “всеобъемлющего” графика, чтобы я повесил его на стену.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;-1&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-1&quot; aria-label=&quot;Anchor link for: -1&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Таксономия Раст Типов&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2025_02_19_tax_main.png&quot; alt=&quot;Taxonomy&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;В итоге я, на основании своих познаний в теории, составил первый вариант такой таксономии. Я очень люблю использовать деревья (особенно бинарные), для выстраивания иерархий, мне кажется что так легче навигироваться и понимать их суть. Сама по себе визуализация и является конечно целью этой публикации, но для интересующихся и неискушённых читателей я привожу некоторые пояснения и ссылки ниже.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;-2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-2&quot; aria-label=&quot;Anchor link for: -2&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
П-тип&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ru.wikipedia.org&#x2F;wiki&#x2F;%D0%A2%D0%B8%D0%BF-%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5&quot;&gt;Тип произведение&lt;&#x2F;a&gt; ни дать, ни взять. Мы компануем несколько типов в один, получаем произведение возможных значений этих типов как новое множество значений. Какие типы в Раст его реализуют?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Кортеж: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch03-02-data-types.html#the-tuple-type&quot;&gt;Tuple&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Структура: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch05-00-structs.html&quot;&gt;Struct&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Кортеж-Структура: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch05-01-defining-structs.html#using-tuple-structs-without-named-fields-to-create-different-types&quot;&gt;Tuple Struct&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Единичная структура: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch05-01-defining-structs.html#unit-like-structs-without-any-fields&quot;&gt;Unit-Like Struct&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Массив: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch03-02-data-types.html#the-array-type&quot;&gt;Array&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;Срез: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch04-03-slices.html&quot;&gt;Slice&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;-3&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-3&quot; aria-label=&quot;Anchor link for: -3&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Σ-тип&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ru.wikipedia.org&#x2F;wiki&#x2F;%D0%A2%D0%B8%D0%BF-%D1%81%D1%83%D0%BC%D0%BC%D0%B0&quot;&gt;Тип-сумма&lt;&#x2F;a&gt; в отличии от П-типа, тип-сумма даёт более строгий контроль над возможными значениями используемых типов.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Перечисление: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch06-00-enums.html&quot;&gt;Tagged Union&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Опцион: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch06-01-defining-an-enum.html#the-option-enum-and-its-advantages-over-null-values&quot;&gt;Option&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Результат: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch09-02-recoverable-errors-with-result.html&quot;&gt;Result&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;-4&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-4&quot; aria-label=&quot;Anchor link for: -4&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Типы-указатели&lt;&#x2F;h2&gt;
&lt;p&gt;Раст имеет возможности для работы с памятью, поэтому язык содержит в себе и ссылки и указатели. Нас же интересуют только “высокоуровневые” концепции.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ссылки: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch04-02-references-and-borrowing.html&quot;&gt;References&lt;&#x2F;a&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;img&#x2F;trpl04-06.svg&quot; alt=&quot;Three tables: the table for s contains only a pointer to the table
for s1. The table for s1 contains the stack data for s1 and points to the
string data on the heap.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Умные указатели
&lt;ul&gt;
&lt;li&gt;Коробка: Аллоцирует значение в куче. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch15-01-box.html#using-boxt-to-point-to-data-on-the-heap&quot;&gt;Box&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Rc&#x2F;Arc: Счётчики ссылок. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch15-04-rc.html#rct-the-reference-counted-smart-pointer&quot;&gt;Reference counters&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ref&#x2F;RefMut + RefCell: Заимствование на уровне исполнения программы. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch15-05-interior-mutability.html&quot;&gt;Runtime borrowing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;-5&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-5&quot; aria-label=&quot;Anchor link for: -5&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Другие типы&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Функции: Не относятся к текущей версии таксономии, поэтому приведены лишь постольку-поскольку.
&lt;ul&gt;
&lt;li&gt;Замыкания: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch13-01-closures.html&quot;&gt;Closures&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;FnOnce: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;ops&#x2F;trait.FnOnce.html&quot;&gt;Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;FnMut: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;ops&#x2F;trait.FnMut.html&quot;&gt;Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fn: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;ops&#x2F;trait.Fn.html&quot;&gt;Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Объекты типажи: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;stable&#x2F;book&#x2F;ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types&quot;&gt;Trait Objects&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Фантомные типы: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;nomicon&#x2F;phantom-data.html&quot;&gt;Phantom Data&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Okxlivro - Post Mortem</title>
        <published>2025-01-27T00:00:00+00:00</published>
        <updated>2025-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            Nikita Bishonen
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/2025-01-03-okxlivro-post-mortem/"/>
        <id>https://bshn.rs/ru/blog/2025-01-03-okxlivro-post-mortem/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/2025-01-03-okxlivro-post-mortem/">&lt;p&gt;Привет! Сегодня я делюсь своими мыслями о написании удобных Раст библиотек. Это первый пост из серии “Post Mortem”, где я буду препарировать разные проекты.
Сегодня на нашем столе будет техническое задание, которое мне дали в одной из компаний после собеседования. Я не люблю тратить своё личное время,
поэтому обычно отказываюсь от прохождения этого этапа, но здесь проект показался мне интересным и я его выполнил. А также получил отказ и обратную связь.
Попробуем исправить то, что не понравилось проверяющему и заодно обсудить изменения.&lt;&#x2F;p&gt;
&lt;p&gt;Как и предыдущий, этот пост я начну с небольшой ликвидации безграмотности. Если вы уверены в своих знаниях специфики биржевой торговли, то смело прыгайте к &lt;a href=&quot;https:&#x2F;&#x2F;bshn.rs&#x2F;ru&#x2F;blog&#x2F;2025-01-03-okxlivro-post-mortem&#x2F;#%D1%81%D1%83%D1%82%D1%8C&quot;&gt;сути&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;portfeli-stakany-i-zakazy&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#portfeli-stakany-i-zakazy&quot; aria-label=&quot;Anchor link for: portfeli-stakany-i-zakazy&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Портфели, стаканы и заказы&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Если вы не знакомы с торгами, то рекомендую перед дальнейшим прочтением изучить &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Kl4-VJ2K8Ik&quot;&gt;небольшое видео об этом&lt;&#x2F;a&gt; или &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ru.wikipedia.org&#x2F;wiki&#x2F;%D0%91%D0%B8%D1%80%D0%B6%D0%B5%D0%B2%D0%BE%D0%B9_%D1%81%D1%82%D0%B0%D0%BA%D0%B0%D0%BD&quot;&gt;статью на Википедии&lt;&#x2F;a&gt;. Далее я излагаю своё понимание темы, которoe может оказаться неточным или неполным.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Итак, в Торгах мы имеем:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Портфель заказов
&lt;ul&gt;
&lt;li&gt;Заказы на продажу (Ask side Order)
&lt;ul&gt;
&lt;li&gt;Идентификатор торговой пары (что на что меняю), объём и цена&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Заказы на покупку (Bid side Order)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Получается такая книга или стакан где мы записываем все заказы и если они пересекаются (у нас есть желающий продать одно яйцо за килограм картошки и другой желающий купить одно яйцо за килограм картошки),
то мы можем исполнить оба заказа.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;upload.wikimedia.org&#x2F;wikipedia&#x2F;commons&#x2F;thumb&#x2F;1&#x2F;14&#x2F;Order_book_depth_chart.gif&#x2F;250px-Order_book_depth_chart.gif&quot; alt=&quot;Стакан&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;суть&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#суть&quot; aria-label=&quot;Anchor link for: суть&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Суть&lt;&#x2F;h2&gt;
&lt;p&gt;Пробуем применять &lt;a href=&quot;&#x2F;blog&#x2F;2024-12-13-rust-micro-structure&quot;&gt;Структуру на Основе Видимости Модулей&lt;&#x2F;a&gt;. Идеей и основной задачей является написание библиотеки для работы с OKX биржей, API должен быть удобен в использовании, а реализация в расширении и поддержкe.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Я решил что стоит пробовать писать идеоматичный, но современный Раст код - использующий асинхронную модель, строгую типизацию и сокрытие реализации.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Здесь всё хорошо, никаких замечаний выявлено не было.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#&quot; aria-label=&quot;Anchor link for: &quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
REST (in peace =)&lt;&#x2F;h3&gt;
&lt;p&gt;Изначально я сделал довольно простую реализацию:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; orderbook_snapshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RestError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; serde_json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Client&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;format!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;MARKET_BOOKS_REST_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;?instId=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;&amp;amp;sz=5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;as_array&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap_or&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;vec!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Order&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;try_from&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;try_collect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #FF5C57);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;as_array&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;unwrap_or&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;vec!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Order&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;try_from&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;try_collect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;apply_snapshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;SnapshotData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;И получил замечание - что решение в лоб и парсинг данных идёт просто через &lt;code&gt;Value&lt;&#x2F;code&gt;. Перепишем это на строгие типы:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; orderbook_snapshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; client&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Client&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RestError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; inner&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;ApiResponse&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; client&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;format!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;MARKET_BOOKS_REST_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;?instId=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;&amp;amp;sz=5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;into_iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;into_iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;from&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;apply_snapshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;SnapshotData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;orderbook&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Детали можно посмотреть в &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;personal1196&#x2F;trainings&#x2F;okxlivro&#x2F;-&#x2F;blob&#x2F;master&#x2F;src&#x2F;rest.rs&quot;&gt;git&lt;&#x2F;a&gt;, но сама реализация почти стандартная.
Отличие в том, что я не делаю прямую десериализацию в публичные типы библиотеки, а использую &lt;code&gt;mod inner {...}&lt;&#x2F;code&gt;. Это сделано из основанного на опыте опасения что:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Биржа имеет нестабильный API, несмотря на версионирование, описание в документации и реальность различаются, особенно когда нету никаких формальных схем;&lt;&#x2F;li&gt;
&lt;li&gt;Биржевое представление неоптимально, например там возвращается массив данных, но элемент всегда один, или сами ставки и предложения это массив из четырёх элементов
один из которых: &lt;code&gt;&quot;0&quot; is part of a deprecated feature and it is always &quot;0&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;-1&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-1&quot; aria-label=&quot;Anchor link for: -1&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Asks &amp;amp; Bids&lt;&#x2F;h3&gt;
&lt;p&gt;Начну с простого, используем все возможности стандартной библиотеки. Есть требование к спискам заказов, они должны быть отсортированы от лучшего к худшему.
Но в зависимости от стороны заказа (покупаем\продаем), сортировать нужно либо по возрастанию (лучше купить дешевле), либо по убыванию (лучше продать дороже) цены.&lt;&#x2F;p&gt;
&lt;p&gt;Изначально я реализовал их таким образом, что различие цен было в использовании обёртки &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;cmp&#x2F;struct.Reverse.html&quot;&gt;Reverse&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Low to high price ordered Map ([`Price`], [`Amount`]) of Asks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Asks&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;BTreeMap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; High to low price ordered Map ([`Price`], [`Amount`]) of Bids.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Bids&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;BTreeMap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Reverse&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Замечание указывало на то, что расширять и поддерживать будет неудобно из-за дублирования логики при отсутствии различий (только &lt;code&gt;Reverse&lt;&#x2F;code&gt;) между ставками и предложениями.
Мне кажется проверяющий хотел бы чего-то другого, но я решил пойти all in и иногда дублировать логику, но разграничить предложения и ставки ещё больше:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; AskPrice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; BidPrice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Reverse&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Делаем разные цены, а также структуры для единичных ставок и предложений, которые используем в модуле &lt;code&gt;realtime&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; lib.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; AskPrice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; price&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; BidPrice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Amount&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; realtime.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; SnapshotData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; UpdateData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Парирую же замечание проверяющая о “дублировании логики” тем, что общую логику нужно реализовывать на уровне &lt;code&gt;Price&lt;&#x2F;code&gt;,
а различия логик можно реализовывать для &lt;code&gt;Bid&lt;&#x2F;code&gt; и &lt;code&gt;Ask&lt;&#x2F;code&gt; раздельно. А наличие строгой типизиации на уровне API библиотеки
даёт хороший пользовательский опыт, поскольку не получится случайно спутать местами ставку и предложение.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-2&quot; aria-label=&quot;Anchor link for: -2&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Stream&lt;&#x2F;h3&gt;
&lt;p&gt;Изначально я использовал подход через каналы отправки сообщений, но затем переписал на вариант, более эргономичный для использования клиентами библиотеки:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;personal1196&#x2F;trainings&#x2F;okxlivro&#x2F;-&#x2F;merge_requests&#x2F;1&#x2F;diffs?diff_id=1224257646&amp;amp;start_sha=dcb0a49c106f39a254e06d2ebeabd912cc508cd0#76f9c51b493a7919f56a79c87fae8b40195e3848&quot;&gt;изменения&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; orderbook_updates&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Pin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Item&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;RealtimeData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RealtimeError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;  ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;  Box&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;pin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;stream!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;next&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;      ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;      yield&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;как мы видим, данный подход ещё требует дополнительных макросов и асинхронные итераторы не являются чем-то родным стандартной библиотеке, продолжаем надееться и ждать.
Замечание полученное здесь относится к проблеме управления соединениями:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; orderbook_updates&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;instrument_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Pin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Item&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;RealtimeData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RealtimeError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;    ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;    Box&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;pin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;stream!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;ws_stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; tokio_tungstenite&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;connect_async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #2DAE58);&quot;&gt;WS_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mut&lt;&#x2F;span&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ws_stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;Message&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;Text&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;message_string&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;into&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;msg&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;next&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Необходимо было выносить эту логику из метода, что очень логично, я люблю паттерн, когда все “ресурсы” передаются как аргументы метода,
в минимально необходимых формах. Это конечно заставило меня немного помучаться с обобщениями. Но спустя десять минут прыганий по коду
tungstenite я нашёл верные типы для ошибок и привёл сигнатуру метода к следующему виду, параллельно разбив один метод на два:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; subscribe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;S&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;channels_with_criterias&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;ChannelWithCriteria&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; write&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; S&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RealtimeError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt; transform_stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;T&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA999C, #565869);&quot;&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; T&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Pin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Stream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Item&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Item&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Также я изменил возвращаемый тип, чтобы поддержать расширение на все возможные типы данных для разных подписок:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; RealtimeData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    Books&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;BooksChannelData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Могу сказать что перечисления в Раст я нахожу удобными и практичными, единственное чего мне сильно не хватает - чтобы варианты перечислений имели “перво классную” поддержку в системе типов языка.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; BooksChannelDelta&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    Snapshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;SnapshotData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    Update&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;UpdateData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; SnapshotData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; UpdateData&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Ask&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Bid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Например реализация сообщений от биржи - по WebSocket соединению к нам может быть доставлена информация как об обновлении портфеля, так и слепок его состояния.
Если не использовать перечисление, то сами данные идентичны и пользователь может перепутать их. В реализации я не только разбил их на варианты,
но и создал новые типы-обёртки для большей безопасности при использовании.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-3&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-3&quot; aria-label=&quot;Anchor link for: -3&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Error&lt;&#x2F;h3&gt;
&lt;p&gt;Обожаю простую, но безумно полезную библиотеку &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;derive_more&#x2F;latest&#x2F;derive_more&#x2F;index.html&quot;&gt;derive_more&lt;&#x2F;a&gt; с процедурными макросами вывода на все случаи жизни, например для создания типов ошибок:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Debug&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Display&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; From&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; CompoundError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;    Realtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; source&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RealtimeError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;    Rest&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; source&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; RestError&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Здесь, благодаря макросам, перечисление становится Раст ошибкой, может быть выведено в виде строки и сконвертировано из низкоуровневых ошибок - всё это без лишнего кода
написанного от руки. Он есть - но генерируется автоматически.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;-4&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-4&quot; aria-label=&quot;Anchor link for: -4&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Дополнительные материалы&lt;&#x2F;h2&gt;
&lt;p&gt;Если вам интересно “поиграть” с примером из данной статьи, то вот &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.com&#x2F;personal1196&#x2F;trainings&#x2F;okxlivro&quot;&gt;полный код проекта&lt;&#x2F;a&gt;.
Также буду благодарен за обратную связь, пожалуйста пишите своим предложения по улучшению проекта в issues на gitlab.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Rust Microservices - Project Structure</title>
        <published>2024-12-13T00:00:00+00:00</published>
        <updated>2024-12-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            Nikita Bishonen
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bshn.rs/ru/blog/2024-12-13-rust-micro-structure/"/>
        <id>https://bshn.rs/ru/blog/2024-12-13-rust-micro-structure/</id>
        
        <content type="html" xml:base="https://bshn.rs/ru/blog/2024-12-13-rust-micro-structure/">&lt;p&gt;Привет! Сегодня я делюсь своими мыслями об удобной мне структуре проекта при разработке микросервисов на расте. Это первый пост из возможной серии “Микросервисы на Расте”. Если я смогу её закончить, то оформлю целую книгу, так что если вы заметили неточность или у вас есть своим мысли по теме поста - буду рад если вы поделитесь ими со мной.
Начну этот пост с небольшой ликвидации безграмотности. Если вы уверены в своих знаниях системы пакетов и модулей в Rust, то смело прыгайте к &lt;a href=&quot;https:&#x2F;&#x2F;bshn.rs&#x2F;ru&#x2F;blog&#x2F;2024-12-13-rust-micro-structure&#x2F;#%D1%81%D0%BE%D0%B2%D0%BC&quot;&gt;сути&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pakety-kreity-i-moduli-v-rast&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#pakety-kreity-i-moduli-v-rast&quot; aria-label=&quot;Anchor link for: pakety-kreity-i-moduli-v-rast&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Пакеты, крейты и модули в Раст&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Если вы не знакомы с Раст, то рекомендую перед дальнейшим прочтением изучить первоисточник - главу &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;book&#x2F;ch07-00-managing-growing-projects-with-packages-crates-and-modules.html&quot;&gt;Managing Growing Projects with Packages, Crates and Modules&lt;&#x2F;a&gt; в официальной документации Раст. Далее я излагаю свой персказ, который может оказаться неточным или неполным.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Итак, в Раст проектах мы имеем:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Пакет содержащий:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Cargo(.toml | .lock)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Один или множество крейтов, каждый из которых имеет:
&lt;ul&gt;
&lt;li&gt;Корень крейта - &lt;code&gt;src&#x2F;(lib.rs | main.rs | bin&#x2F;*.rs)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Модули
&lt;ul&gt;
&lt;li&gt;встроенные - &lt;code&gt;mod _name_ { _body }&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;отдельными файлами - &lt;code&gt;mod _name_;&lt;&#x2F;code&gt; + &lt;code&gt;src&#x2F;(_name_.rs | _name_&#x2F;mod.rs)&lt;&#x2F;code&gt;
Получается такая матрёшка или сказка о Кощее Бессмертном - Игла (модуль) в яйце, яйцо (крейт) в курице, курица (пакет) в сундуке (проекте).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_01.png&quot; alt=&quot;Пакеты в Раст&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Давайте же разбираться какие есть правила доступа к модулям.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Модули могут быть частными (скрытыми) и публичными.
&lt;ol&gt;
&lt;li&gt;По-умолчанию модули частные.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Сущности внутри модуля тоже могут быть частными и публичными.
&lt;ol&gt;
&lt;li&gt;По-умолчанию сущности частные.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;А далее начинаются интересные взаимодействия и комбинации, которые предлагаю рассмотреть на примере кода.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; grandchildren&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; neighbour&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Визуально сама структура выглядит следующим образом:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_02.png&quot; alt=&quot;Структура&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;На этом примере хочу показать вам возможные связи между модулями и сущностями (в данном примере мы ограничиваемся пустыми структурами).
Разобьём это на несколько ситуацией, различать их мы будем по вызывающей стороне.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#&quot; aria-label=&quot;Anchor link for: &quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Что может родительский модуль?&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;	children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;	children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::grandchildren::Public; &#x2F;&#x2F; Fails due to privacy of module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Выше я привожу кусочек теста для родительского модуля, как мы видим, доступ имеется к обоим (частному и публичному) дочерним модулям, но только к публичным структурам. Доступа же к частным “внукам” и их публичным структурам не имеется. Визуально это выглядит следующим образом:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_03.png&quot; alt=&quot;Родительский&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-1&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-1&quot; aria-label=&quot;Anchor link for: -1&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Что может дочерний модуль?&lt;&#x2F;h3&gt;
&lt;p&gt;Для этого мы сделаем дополнение и добавим в родительский модуль две структуры, по аналогии с дочерними.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibility of super model and another sub-models of module one level above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; super::children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; self::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E78284, #2DAE58);&quot;&gt;    self&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;grandchildren&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_04.png&quot; alt=&quot;Дочерний&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Как мы можем видеть, щупальца нашего детятки раскинулись достаточно широко и лишь частные структуры соседних и дочерних модулей им недоступны. А вот частные структуры родительского модуля вполне в зоне досягаемости.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-2&quot; aria-label=&quot;Anchor link for: -2&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Что может правнук(чка)?&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibility of super model and another sub-models of module two levels above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; super::super::children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_05.png&quot; alt=&quot;Правнук&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Для правнука ситуация схожая, решил показать её для лучшего понимания многоуровневой работы этого механизма в Раст.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-3&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-3&quot; aria-label=&quot;Anchor link for: -3&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Что может сосед?&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;К сожалению я только на этом этапе заметил что все диаграммы до включают соседа в модуль родителя, на самом деле он конечно находится рядом, а не внутри родителя. Диаграмма ниже содержит корректное расположение этого модуля.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibilit of sub-modules inside another module on the same level.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	crate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_private::Private; &#x2F;&#x2F; Fails due to privacy of module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_private::Public; &#x2F;&#x2F; Fails due to privacy of module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;	crate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of a module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;	&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::grandchildren::Public; &#x2F;&#x2F; Fails due to privacy of a module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;2024_12_13_rust_micro_structure_06.png&quot; alt=&quot;Соседский&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;У соседа всё достаточно скучно - только публичные сущности и пути к ним являются доступными. При этом стоит заметить что модуль родителя не является публичным, при этом сосед всё равно его видит 👀&lt;&#x2F;p&gt;
&lt;h2 id=&quot;совм&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#совм&quot; aria-label=&quot;Anchor link for: совм&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
СОВМ&lt;&#x2F;h2&gt;
&lt;p&gt;Или Структура на Основе Видимости Модулей. Идеей является то, что в Расте мы имеем уже определённые правила доступа (подробнее о которых я рассказал выше) к сущностям модулей в зависимости от их взаимоотношений (кем вызывающий модуль приходится вызываемому).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Я решил что и структура проекта должна быть изложена исходя из этих особенностей языка Раст, чтобы быть более идиоматичной. Идея новая и по мере её обкатывания, я буду обновлять этот пост.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Чтобы получить идиоматичную структуру проекта, мы должны располагать модули на основании того, кто и что должен видеть. Является ли эта часть кода чем-то используемым во всём сервисе? Выносим её как можно выше. Является ли другая часть кода специфичной? Выделяем её в отдельную ветвь или прячем поглубже.
Суть в том что модули не должны быть декомпозированы согласно бизнес доменам (по-крайней мере это не должно быть основой деления). Ведь в случае микросервисной архитектуры это должны быть не модули, а другие сервисы (ну или другие пакеты раста для монолитных приложений). Таким образом мы стремимся к заветному золотому соотношению &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Larry_Constantine#Structured_design&quot;&gt;loose coupling and high cohesion&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;-4&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-4&quot; aria-label=&quot;Anchor link for: -4&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
TL;DR&lt;&#x2F;h3&gt;
&lt;p&gt;Как же я вижу использование этого подхода в написании микросервисов? Предлагаю не тратить ещё больше вашего времени на чтение моих мыслей, а посмотреть на шаблон:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;! This is the base service crate. Better to make it a library, so functionality regarding how&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;! exactly to run it will be stored separately inside one main.rs or different bins.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; interfaces&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; graphql&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; http&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; grpc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; core&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; api&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; resources&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; db&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; kafka&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; third_party_integration&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Вы можете создать новый пакет, в котором будет два крейта:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;main отвечает лишь за запуск приложения&lt;&#x2F;li&gt;
&lt;li&gt;lib хранит структуру и используется в main, tests (интеграционных) и в дополнительных “бинах” если потребуется&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;-5&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-5&quot; aria-label=&quot;Anchor link for: -5&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Реальный пример&lt;&#x2F;h3&gt;
&lt;p&gt;В этом примере изменены некоторые названия, но это реальная структура одного из нескольких сервисов. Собственно их написание и послужило толчком к выведению некоторой общей теории относительно структурирования микросервисов на расте.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; └──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; events_processor.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; core&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; api.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; configuration.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; └──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; mod.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; interfaces&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; graphql&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; │  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; mod.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; │  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; mutations.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; │  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; queries.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; │  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; └──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; subscriptions.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;│  &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; └──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; mod.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; lib.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; main.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;└──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; resources&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; node_proxy.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; indexer_proxy.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; db.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; mod.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    ├──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; reservoir_proxy.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    └──&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt; real_time_data_ws.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;-6&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-6&quot; aria-label=&quot;Anchor link for: -6&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Мой опыт&lt;&#x2F;h3&gt;
&lt;p&gt;Могу сказать что эту структуру я нахожу удобной, поскольку она совмещает в себе преимущества старых добрых - трёхслойных архитектур и, применимых к микросервисам, гексогональных архитектур. Мы разделяем наше приложение на три ветви:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Ресурсы&lt;&#x2F;code&gt;, сюда попадает всё, что находится вне нашего сервиса и к чему мы являемся потребителями. Базы данных, другие сервисы, брокеры сообщений (частично). Всё где мы инициируем общение и где мы знаем о собеседнике больше, чем он о нас. (Раньше я называл эту часть &lt;code&gt;clients&lt;&#x2F;code&gt;, но имя ресурсы мне сейчас кажется более подходящим). Основная задача ресурсов - справиться со спецификой взаимодействия с этими ресурсами. Здесь могут лежать реализации типажей кодирования и декодирования наших типов данных под определённую базу данных, также сюда пишем “прокси”, которые трансформируют схему других сервисов в ту, которой оперируем мы внутри сервиса.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Интерфейсы&lt;&#x2F;code&gt;, сюда складываем всё, что является входными точками для запросов к нашему сервису. HTTP&#x2F;gRPC API, GraphQL, даже брокеры сообщений, если это часть обработки входящих запросов, всё идёт сюда. Также как и ресурсы, здесь мы стараемся отсечь всю специфику связанную с конкретным механизмом взаимодействия клиентов с нами, как с сервером (поэтому раньше я называл эту часть &lt;code&gt;servers&lt;&#x2F;code&gt;). Например все десериализации запросов и сериализации ответов, должны быть реализованы тут. Дальше мы должны работать с “чистыми” типами.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Ядро&lt;&#x2F;code&gt;, это самое “чистое” и “важное” место нашего сервиса. Здесь реализуется основная бизнес-логика. Здесь мы оперируем не пришедшим по сети JSON, а его статически типизированным и проверенным представлением. Из ядра мы можем вызывать ресурсы, но желательно ничего не знать об интерфейсах. Однако мы не должны иметь доступа к низкоуровневым концептам ресурсов. Только к публичному API.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Как же тут помогает расположение модулей? Мы видим что все три ветки являются соседями друг-другу, значит могут знать лишь публичные вещи, а частности являются безопасными для изменения (например смена базы данных или поддержка REST бок о бок с gRPC).
Внутри же ветвей мы идём от общего к частному и также разделяем независимые части на ветви.
&lt;code&gt;graphql&lt;&#x2F;code&gt; состоит из независимых &lt;code&gt;queries&lt;&#x2F;code&gt;, &lt;code&gt;mutations&lt;&#x2F;code&gt;, &lt;code&gt;subscriptions&lt;&#x2F;code&gt;, но общую схему составляет в корневом модуле:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;! graphql&#x2F;mod.rs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; async&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Mutation&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Subscription&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#99D1DB, #ADB1C2);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;from_env&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; pool&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; database&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;connect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #565869);&quot;&gt;database&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;await&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; producer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt; kafka&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;build_producer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #565869);&quot;&gt;kafka&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;    Ok&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Schema&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Mutation&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt; Subscription&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;enable_federation&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;enable_subscription_in_federation&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;При этом каждый под-модуль будет вызывать публичные “чистые” методы из &lt;code&gt;core&#x2F;api.rs&lt;&#x2F;code&gt;.
&lt;code&gt;api.rs&lt;&#x2F;code&gt; же в моём примере содержит общие типы в корне (как частные, так и публичные), полный доступ к которым имеют его подмодули &lt;code&gt;api::queries&lt;&#x2F;code&gt; и &lt;code&gt;api::commands&lt;&#x2F;code&gt;, но частные типы и реализации самого модуля &lt;code&gt;api&lt;&#x2F;code&gt; недоступны никому, кроме его подмодулей.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;-7&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#-7&quot; aria-label=&quot;Anchor link for: -7&quot;&gt;&lt;i class=&quot;icon&quot;&gt;&lt;&#x2F;i&gt;&lt;&#x2F;a&gt;
Дополнительные материалы&lt;&#x2F;h2&gt;
&lt;p&gt;Если вам интересно “поиграть” с примером из данной статьи, то вот полный код проекта из главы про модули:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#C6D0F5, #565869); background-color: light-dark(#303446, #FAFBFC);&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #ADB1C2);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;clippy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; dead_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; path_statements&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt;    println!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #CF9C00);&quot;&gt;Hello, modules privacy!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#A6D189, #ADB1C2);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; grandchildren&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            pub&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt; struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);font-style: italic;&quot;&gt; Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;            &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibility of super model and another sub-models of module two levels above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;                &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; super::super::children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;                super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibility of super model and another sub-models of module one level above.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; super::children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;            super&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;            &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; self::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E78284, #2DAE58);&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;grandchildren&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibility of sub-modules inside current module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_private::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;        children_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;        children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; children_public::grandchildren::Public; &#x2F;&#x2F; Fails due to privacy of module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;mod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EF9F76, #565869);&quot;&gt; neighbour&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; Test visibilit of sub-modules inside another module on the same level.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#8CAAEE, #09A1ED);font-style: italic;&quot;&gt; test_visibility&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        crate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_private::Private; &#x2F;&#x2F; Fails due to privacy of module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_private::Public; &#x2F;&#x2F; Fails due to privacy of module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::Private; &#x2F;&#x2F; Fails due to privacy of struct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#CA9EE6, #F767BB);&quot;&gt;        crate&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #565869);&quot;&gt;children_public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#81C8BE, #ADB1C2);&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E5C890, #13BBB7);font-style: italic;&quot;&gt;Public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::grandchildren::Private; &#x2F;&#x2F; Fails due to privacy of a module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt;        &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);font-style: italic;&quot;&gt; crate::parent::children_public::grandchildren::Public; &#x2F;&#x2F; Fails due to privacy of a module&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#949CBB, #ADB1C2);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
</feed>
