<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: edo1z</title>
    <description>The latest articles on DEV Community by edo1z (@edo1z).</description>
    <link>https://dev.to/edo1z</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F762088%2F5f274b6c-37db-4f6d-9ab0-506cad7b2727.png</url>
      <title>DEV Community: edo1z</title>
      <link>https://dev.to/edo1z</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/edo1z"/>
    <language>en</language>
    <item>
      <title>Rust(Rocket)でtracingを使った詳細なエラーログ出力とエラーハンドリングの改善をしてみました</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Wed, 06 Dec 2023 13:14:12 +0000</pubDate>
      <link>https://dev.to/edo1z/rustrocketdetracingwoshi-tutaxiang-xi-naeraroguchu-li-toerahandoringunogai-shan-wositemimasita-424n</link>
      <guid>https://dev.to/edo1z/rustrocketdetracingwoshi-tutaxiang-xi-naeraroguchu-li-toerahandoringunogai-shan-wositemimasita-424n</guid>
      <description>&lt;p&gt;RustのWebフレームワークの&lt;a href="https://rocket.rs/"&gt;Rocket&lt;/a&gt;で作っているWebアプリで、tracingを使った詳細なエラーログ出力とエラーハンドリングの改善をしてみました。&lt;/p&gt;

&lt;h2&gt;
  
  
  前提
&lt;/h2&gt;

&lt;p&gt;クリーンアーキテクチャっぽい構成を想定しています。controller, use_case, repositoryがあります。repositoryではsqlxでPostgreSQLを使います。&lt;/p&gt;

&lt;h3&gt;
  
  
  リポジトリ
&lt;/h3&gt;

&lt;p&gt;リポジトリは下記です。&lt;br&gt;
&lt;a href="https://github.com/edo1z/rust-rocket-sqlx-sample"&gt;https://github.com/edo1z/rust-rocket-sqlx-sample&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  tracingを使った詳細なエラーログ出力
&lt;/h2&gt;

&lt;p&gt;エラー発生箇所のファイルパス、行番号、エラー発生までの経緯（どのファイルのどの関数を辿ったのか）などを、出力するために、&lt;a href="https://github.com/tokio-rs/tracing/tree/v0.1.x"&gt;tracing&lt;/a&gt;クレートを利用しました。&lt;/p&gt;
&lt;h3&gt;
  
  
  ログ出力例
&lt;/h3&gt;

&lt;p&gt;結果的にこのようなログが出力されるようになりました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2023-12-05T07:43:24.644738Z ERROR user_controller/update{id=12}:user_use_case/update{id=12}:user_repo/update{id=12}: rust_rocket_sqlx_sample::repositories::user_repo: [DbRepoError::SqlxError] no rows returned by a query that expected to return at least one row (src/repositories/user_repo.rs:85)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;user_controller&lt;/code&gt;の&lt;code&gt;update&lt;/code&gt;関数（引数idが12）から、&lt;code&gt;user_use_case&lt;/code&gt;の&lt;code&gt;update&lt;/code&gt;関数（引数が12）に行き、そこから、&lt;code&gt;user_repo&lt;/code&gt;の&lt;code&gt;update&lt;/code&gt;関数（引数が12）に行って、そこでエラーが発生しているということが分かりまっす。そして、エラー発生箇所は、user_repo.rsの85行目であり、エラーは&lt;code&gt;DbRepoError::SqlxError&lt;/code&gt;であり、データがなかったことが分かります。分かりやすくなりました！&lt;/p&gt;

&lt;h3&gt;
  
  
  コードサンプル
&lt;/h3&gt;

&lt;p&gt;repositoryの関数はこんな感じになっております。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[instrument(name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user_repo/update"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;skip_all,&lt;/span&gt; &lt;span class="nd"&gt;fields(id&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nd"&gt;id))]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;PgConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DbRepoError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;query_as!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"UPDATE users SET name = $1 WHERE id = $2 RETURNING *"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.fetch_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;.await&lt;/span&gt;
    &lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nd"&gt;log_into!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DbRepoError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  instrument属性
&lt;/h4&gt;

&lt;p&gt;最初の行の&lt;code&gt;instrument&lt;/code&gt;属性は、&lt;a href="https://github.com/tokio-rs/tracing/tree/v0.1.x"&gt;tracing&lt;/a&gt;の機能で、これを書いておくと、エラーログ出力時に、ログ発生の経緯にこの関数のnameや、引数が出力されます。controller, use_case, repositoryに全部書いておくと、全部順番に出力されるので、一目でログ出力時の実行順序が分かります。ただ、ログに引数の値を出力させるというのは、かなり危険な香りがしますので、基本的には&lt;code&gt;skip_all&lt;/code&gt;を設定して、表示させても問題なく、且つ、表示させたいものは、個別に&lt;code&gt;fields&lt;/code&gt;で設定するという方針にしています。これは、危ないから使わないという選択肢もあるのかもなーとは思いました。どうもデフォルトでOFFには簡単にはできなそうだったのですが、もしデフォルトOFFができると、より安心かなあと思っております。&lt;/p&gt;

&lt;h4&gt;
  
  
  log_into!マクロ
&lt;/h4&gt;

&lt;p&gt;最後の行の、&lt;code&gt;log_into!&lt;/code&gt;マクロは下記になっております。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[macro_export]&lt;/span&gt;
&lt;span class="nd"&gt;macro_rules!&lt;/span&gt; &lt;span class="n"&gt;log_into&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$error:expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$target_type:ty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;converted_error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$target_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$error&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;error!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} ({}:{})"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;converted_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;file!&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nd"&gt;line!&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;converted_error&lt;/span&gt;
    &lt;span class="p"&gt;}};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;エラーを&lt;code&gt;target_type&lt;/code&gt;の別のエラーに変換して、そのエラーをファイルパスと行番号と共に、tracingの&lt;code&gt;error!&lt;/code&gt;を使ってログ出力するマクロになります。ただの関数ですと、ファイルパス・行番号はこの関数のファイルパス及び行番号になりますので、それもあって、マクロにしております。もしファイルパス・行番号が不要であれば、自動でエラーは変換できるので、このようなマクロを使う必要はありません。&lt;/p&gt;

&lt;h2&gt;
  
  
  エラーハンドリングの改善
&lt;/h2&gt;

&lt;p&gt;use_caseでrepository等で発生したエラーの詳細を把握し、細かくエラーハンドリングできるようにしつつ、なるべくシンプルにしたいと考えていまして、現状としては、結構いい感じな気がしてます。&lt;/p&gt;

&lt;h3&gt;
  
  
  ポイント① DbRepoErrorでラップ
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;DbRepoError&lt;/code&gt;は下記です。&lt;a href="https://github.com/dtolnay/thiserror"&gt;thiserror&lt;/a&gt;クレートという便利ツールを使うことで、記述量が激減しました。&lt;code&gt;from&lt;/code&gt;アトリビュートを設定することで、&lt;code&gt;sqlx::Error&lt;/code&gt;は&lt;code&gt;DbRepoError::SqlxError&lt;/code&gt;に自動変換されます。これで、各エラーの詳細を残しつつ、&lt;code&gt;DbRepoError&lt;/code&gt;としてuse_caseに渡せるようになりました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;thiserror&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Error)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;DbRepoError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"[DbRepoError::SerdeError] {0}"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="nf"&gt;SerdeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;#[from]&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"[DbRepoError::SqlxError] {0}"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="nf"&gt;SqlxError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;#[from]&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Dummy error for testing"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;DummyTestError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ポイント② use_caseで詳細をハンドリングしつつAppErrorに自動変換
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;AppError&lt;/code&gt;は現在&lt;a href="https://github.com/edo1z/rust-rocket-sqlx-sample/blob/v0.2.0/src/error/app_error.rs"&gt;こちら&lt;/a&gt;のようになっております。&lt;code&gt;DbRepoError&lt;/code&gt;が自動的に&lt;code&gt;AppError::DbError&lt;/code&gt;に変換されるようになっています。また、Rocketの&lt;code&gt;Responder&lt;/code&gt;が実装されており、レスポンスにそのまま&lt;code&gt;AppError&lt;/code&gt;が使えるようになっております。そして、レスポンス時のステータスコードも紐づけされています。その他、anyhowを真似した&lt;code&gt;app_err&lt;/code&gt;関数と、&lt;code&gt;app_err!&lt;/code&gt;, &lt;code&gt;app_err_bail!&lt;/code&gt;, &lt;code&gt;app_err_ensure!&lt;/code&gt;マクロを作成しました。&lt;/p&gt;

&lt;h4&gt;
  
  
  AppErrorのコード（一部）
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Error)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Database Error"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="nf"&gt;DbError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;#[from]&lt;/span&gt; &lt;span class="n"&gt;DbRepoError&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Bad Request"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Unauthorized"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Unauthorized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Forbidden"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Forbidden&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Not Found"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"Internal Server Error"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;InternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[error(&lt;/span&gt;&lt;span class="s"&gt;"{message}"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;CustomError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CustomError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;DbError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BadRequest&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Unauthorized&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Forbidden&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NotFound&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InternalServerError&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CustomError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  use_caseのコードサンプル
&lt;/h4&gt;

&lt;p&gt;下記の&lt;code&gt;delete&lt;/code&gt;は、&lt;code&gt;from&lt;/code&gt;を使って自動変換させています。&lt;code&gt;update&lt;/code&gt;では、対象データが存在しない場合は、&lt;code&gt;BadRequest&lt;/code&gt;エラーを返すようにしています。このように、use_caseで、細かいエラーハンドリングが出来るようになりました。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[instrument(name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user_use_case/update"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;skip_all,&lt;/span&gt; &lt;span class="nd"&gt;fields(id&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nd"&gt;id))]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db_con&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;DbCon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;repos&lt;/span&gt;
        &lt;span class="py"&gt;.user&lt;/span&gt;
        &lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;db_con&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nn"&gt;DbRepoError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;SqlxError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RowNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BadRequest&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[instrument(name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user_use_case/delete"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;skip_all,&lt;/span&gt; &lt;span class="nd"&gt;fields(id&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nd"&gt;id))]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_con&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;DbCon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;repos&lt;/span&gt;
        &lt;span class="py"&gt;.user&lt;/span&gt;
        &lt;span class="nf"&gt;.delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;db_con&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  今後やりたいこと
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;メトリクスの収集&lt;/li&gt;
&lt;li&gt;Datadogで集計・グラフ表示&lt;/li&gt;
&lt;li&gt;Datadog経由でSlack通知&lt;/li&gt;
&lt;li&gt;レスポンスのjson化（今エラーメッセージがテキスト）&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>rocket</category>
      <category>tracing</category>
      <category>sqlx</category>
    </item>
    <item>
      <title>c++23で順列を扱う</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Wed, 27 Sep 2023 07:23:01 +0000</pubDate>
      <link>https://dev.to/edo1z/c23deshun-lie-woxi-u-3bl8</link>
      <guid>https://dev.to/edo1z/c23deshun-lie-woxi-u-3bl8</guid>
      <description>&lt;h2&gt;
  
  
  c++23にする
&lt;/h2&gt;

&lt;p&gt;下記でc++23でコンパイルできる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;g++ &lt;span class="nt"&gt;-std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c++23 hoge.cpp &lt;span class="nt"&gt;-o&lt;/span&gt; hoge.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vscodeのコンパイルするタスクも下記でc++23でコンパイルできる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "c++ build for AtCoder",
      "type": "shell",
      "command": "g++",
      "args": [
        "-g",
        "-O0",
        "-std=c++23", 
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}.out"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VSCodeのC/C++拡張機能は、デフォルトでC++17までの機能をサポートしていて、c++20以上を利用する際にエディタでエラーが出る場合がある。&lt;code&gt;.vscode/c_cpp_properties.json&lt;/code&gt;に下記を設定することで、拡張機能のc++バージョンを変更できるらしい。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "configurations": [
        {
            "name": "Linux",
            "includePath": ["${workspaceFolder}/**"],
            "defines": [],
            "compilerPath": "/usr/bin/g++",
            "cStandard": "c17",
            "cppStandard": "c++23",
            "intelliSenseMode": "gcc-x64",
            "compilerArgs": ["-std=c++23"]
        }
    ],
    "version": 4
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  順列
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ranges::next_permutation(hoge)&lt;/code&gt;を使うと、引数hogeのvectorに対する、順列のパターンの次を出してくれる。[0,1,2]を入れると、[0,2,1]を返す。[0,2,1]を入れると[1,0,2]を返す。多分。要するに、全パターンを順番に取得する場合は、しっかりと昇順にソートしてから渡す必要がある。&lt;code&gt;iota(hoge.begin(), hoge.end(), 0)&lt;/code&gt;は、hogeの最初から最後までを0から始まる連続する数値で埋める関数。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;bits/stdc++.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;iota&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;next_permutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;上記の実行結果は下記になる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;012
021
102
120
201
210
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cpp</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Building a Clean Architecture with Rust's Rocket and sqlx</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Mon, 25 Sep 2023 06:33:23 +0000</pubDate>
      <link>https://dev.to/edo1z/building-a-clean-architecture-with-rusts-rocket-and-sqlx-a-deep-dive-45kn</link>
      <guid>https://dev.to/edo1z/building-a-clean-architecture-with-rusts-rocket-and-sqlx-a-deep-dive-45kn</guid>
      <description>&lt;p&gt;I tried my best to create a clean architecture with Rust Rocket and sqlx.&lt;br&gt;
I tried my best to create a state that is easy to test and mock, while also separating modules in a nice way.&lt;/p&gt;
&lt;h2&gt;
  
  
  We've done something similar before at Axum
&lt;/h2&gt;

&lt;p&gt;I used to try to do the same thing with Axum. The repository with the highest number of stars in my history is below.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/edo1z"&gt;
        edo1z
      &lt;/a&gt; / &lt;a href="https://github.com/edo1z/rust-axum-sqlx-sample"&gt;
        rust-axum-sqlx-sample
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Rust Axum+SQLx Sample
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-rust-axum-sqlx-sample"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-axum-sqlx-sample#rust-axum-sqlx-sample"&gt;rust-axum-sqlx-sample&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="user-content-install"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-axum-sqlx-sample#install"&gt;Install&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/web3ten0/rust-axum-sqlx-1.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; rust-axum-sqlx-1/local
docker-compose up -d
sh scripts/exec_init_db&lt;/pre&gt;

&lt;/div&gt;
&lt;h2 id="user-content-migration"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-axum-sqlx-sample#migration"&gt;Migration&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;参照: &lt;a href="https://github.com/launchbadge/sqlx/tree/master/sqlx-cli"&gt;https://github.com/launchbadge/sqlx/tree/master/sqlx-cli&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; local/scripts
sh migrate add -r users
sh migrate run
sh migrate revert&lt;/pre&gt;

&lt;/div&gt;
&lt;h2 id="user-content-swagger"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-axum-sqlx-sample#swagger"&gt;Swagger&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="user-content-swagger-uiのurl"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-axum-sqlx-sample#swagger-ui%E3%81%AEurl"&gt;swagger-uiのURL&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://localhost:8001" rel="nofollow"&gt;http://localhost:8001&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/edo1z/rust-axum-sqlx-sample"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The version of Axum in this repository is already quite old, so I think the whole thing needs to be modified if you try to do it now. Also, use_case is not a Trait, so it may be difficult to create mocks.&lt;/p&gt;

&lt;p&gt;However, the code is rather simple (in my opinion), so I think it is good in terms of simplicity.&lt;/p&gt;

&lt;p&gt;However, the DB Pool is passed to the repository, so each time a function in the repository is executed, it gets a connection from the Pool. I wonder if this is the difference between this version of Rocket and the current version.&lt;/p&gt;

&lt;p&gt;I wonder if getting and destroying a connection every time a function is executed is relatively inefficient compared to continuing to use the same connection for a single request. (I have not measured this, but I asked ChatGPT and they said yes. I think it is basically impossible (and complicated) to do things such as crossing multiple repositories or waiting for a response from an external service before committing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository of the Rocket version we made this time
&lt;/h2&gt;

&lt;p&gt;The repository of this Rocket version is below. Please star it if you like!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/edo1z"&gt;
        edo1z
      &lt;/a&gt; / &lt;a href="https://github.com/edo1z/rust-rocket-sqlx-sample"&gt;
        rust-rocket-sqlx-sample
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A clean architecture style Sample using Rust's Rocket, sqlx and PostgreSQL.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-rust-rocket-sqlx-sample"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-rocket-sqlx-sample#rust-rocket-sqlx-sample"&gt;rust-rocket-sqlx-sample&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/055244968e5f0b840b01f2abbf7c3af1c2b8e12c5ec40095106e2779c67e6a0d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6e657433692f727573742d726f636b65742d73716c782d73616d706c65"&gt;&lt;img src="https://camo.githubusercontent.com/055244968e5f0b840b01f2abbf7c3af1c2b8e12c5ec40095106e2779c67e6a0d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6e657433692f727573742d726f636b65742d73716c782d73616d706c65" alt="GitHub"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b2d84b656622d7784b395f47dc9554642ecbf492c4e209a20cfee6c51a4c6f8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6e657433692f727573742d726f636b65742d73716c782d73616d706c65"&gt;&lt;img src="https://camo.githubusercontent.com/b2d84b656622d7784b395f47dc9554642ecbf492c4e209a20cfee6c51a4c6f8b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6e657433692f727573742d726f636b65742d73716c782d73616d706c65" alt="GitHub code size in bytes"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/73434d75523fa252c75f8a26081673445c712adca8f9abab9a3acad8f2c6117f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6e657433692f727573742d726f636b65742d73716c782d73616d706c65"&gt;&lt;img src="https://camo.githubusercontent.com/73434d75523fa252c75f8a26081673445c712adca8f9abab9a3acad8f2c6117f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6e657433692f727573742d726f636b65742d73716c782d73616d706c65" alt="GitHub last commit (by committer)"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c9857238e2f8e04923f1f204e246d947e21eae47982e5542621521dad0a743f0/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f6e65743369"&gt;&lt;img src="https://camo.githubusercontent.com/c9857238e2f8e04923f1f204e246d947e21eae47982e5542621521dad0a743f0/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f6e65743369" alt="X (formerly Twitter) Follow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A clean architecture style Sample using Rust's &lt;a href="https://rocket.rs/" rel="nofollow"&gt;Rocket&lt;/a&gt;(v0.5), &lt;a href="https://github.com/launchbadge/sqlx"&gt;sqlx&lt;/a&gt;(v0.6) and PostgreSQL.&lt;/p&gt;
&lt;h2 id="user-content-how-to-use"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-rocket-sqlx-sample#how-to-use"&gt;How to Use&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/net3i/rust-rocket-sqlx-sample
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; rust-rocket-sqlx-sample
docker-compose up -d
cp .env.example .env
sh migrate.sh
cargo &lt;span class="pl-c1"&gt;test&lt;/span&gt; -- --test-threads=1
cargo run&lt;/pre&gt;

&lt;/div&gt;
&lt;h2 id="user-content-overview-of-how-it-works"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-rocket-sqlx-sample#overview-of-how-it-works"&gt;Overview of how it works&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use Rocket's &lt;a href="https://api.rocket.rs/v0.5-rc/rocket_db_pools/index.html" rel="nofollow"&gt;rocket_db_pools&lt;/a&gt; to retrieve DB Pool connections from Controller arguments. This is passed as an argument to use_case, which passes the connection as an argument to each function in the repository. Only one connection is used per request, and it is returned to the Pool as soon as the request is processed.&lt;/p&gt;
&lt;h3 id="user-content-mocking"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-rocket-sqlx-sample#mocking"&gt;Mocking&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Since use_case and repository are Trait, mock can be easily created by &lt;a href="https://github.com/asomers/mockall"&gt;mockall&lt;/a&gt; when testing.&lt;/p&gt;
&lt;h3 id="user-content-db-transaction"&gt;&lt;a class="heading-link" href="https://github.com/edo1z/rust-rocket-sqlx-sample#db-transaction"&gt;DB Transaction&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;DB transactions are basically assumed to be used only within each function of repository, but transactions can be generated from DB Pool connections on the use_case side if necessary. However, since the functions in repository do not accept…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/edo1z/rust-rocket-sqlx-sample"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Both use_case and repository are Trait, so it is easier to create mocks.&lt;/li&gt;
&lt;li&gt;The repository functions are now passed only references to connections obtained from the DB Pool, which I think is a bit more efficient than the Axum version above. I think it is a little more efficient than the Axum version above.

&lt;ul&gt;
&lt;li&gt;A connection is obtained from the Pool for each request, and that connection is used throughout the same request. The connection is returned (discarded) when the request is finished.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Since the connection is passed to each function of repository, it is possible to create a transaction on the use_case side and have it commit after multiple repository functions are executed, if you want to do so.&lt;/li&gt;
&lt;li&gt;It is easy to do controller, use_case, and repository (integration test).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Points that annoyed me
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Transaction handling

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/sqlx/0.6.3/sqlx/struct.Transaction.html#"&gt;Transaction&lt;/a&gt; and &lt;a href="https://docs.rs/sqlx/0.6.3/sqlx/pool/%20PoolConnection.html"&gt;PoolConnection&lt;/a&gt;, it was difficult to use mockall.automock while using a repository function that can receive both (I eventually stopped using a function that can receive both).&lt;/li&gt;
&lt;li&gt;As a result of the above, I can no longer use Transaction's Rollback to clear the table state when testing repository. (I now truncate before testing).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Compared to the Axum version, the code around DB connection is a little less simple.

&lt;ul&gt;
&lt;li&gt;But it is inefficient to pass a Pool to a function, and it is difficult to use transactions, so I thought it was good.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I want to do in the future
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I would like to introduce SeaORM.&lt;/li&gt;
&lt;li&gt;I want to make it easy to use transactions in testing.&lt;/li&gt;
&lt;li&gt;Currently, Rocket's sqlx is 0.6, but SeaORM is 0.7. Maybe we will stop using Rocket's db related libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I thought Axum and Rocket were nice.&lt;/li&gt;
&lt;li&gt;I thought it was transaction complicated.&lt;/li&gt;
&lt;li&gt;Please star &lt;a href="https://github.com/net3i/rust-rocket-sqlx-sample"&gt;repository&lt;/a&gt; if you like!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>rocket</category>
      <category>sqlx</category>
      <category>cleanarchitecture</category>
    </item>
    <item>
      <title>m1 macのc++でOpenGLを使ってテトリスを作ってみた</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Sun, 21 Aug 2022 08:09:00 +0000</pubDate>
      <link>https://dev.to/edo1z/m1-macnocdeopenglwoshi-tutetetorisuwozuo-tutemita-1aaj</link>
      <guid>https://dev.to/edo1z/m1-macnocdeopenglwoshi-tutetetorisuwozuo-tutemita-1aaj</guid>
      <description>&lt;p&gt;m1 macの、c++とOpenGLで簡易的なテトリスを作りました。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k9tf3_0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/89882017/185781360-88bbbada-200b-4027-9e5a-2435e5a6da31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k9tf3_0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/89882017/185781360-88bbbada-200b-4027-9e5a-2435e5a6da31.png" alt="thumb" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  リポジトリ
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/web3ten0/cpp-opengl-tetris"&gt;https://github.com/web3ten0/cpp-opengl-tetris&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  実行してみてる動画
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://user-images.githubusercontent.com/89882017/185777309-9afa6109-ba77-42e9-bd1e-2e37c981b26a.mp4"&gt;https://user-images.githubusercontent.com/89882017/185777309-9afa6109-ba77-42e9-bd1e-2e37c981b26a.mp4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=X1YzFl31W7c"&gt;https://www.youtube.com/watch?v=X1YzFl31W7c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  動作環境
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;m1 mac
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
Darwin mac.local 21.6.0 Darwin Kernel Version 21.6.0:
Sat Jun 18 17:05:47 PDT 2022&lt;span class="p"&gt;;&lt;/span&gt; root:xnu-8020.140.41~1/RELEASE_ARM64_T8101 arm64

❯ brew config
HOMEBREW_VERSION: 3.5.9
CPU: octa-core 64-bit arm_firestorm_icestorm
Clang: 13.1.6 build 1316
macOS: 12.5-arm64
CLT: 13.4.0.0.1.1651278267
Xcode: 13.4.1
Rosetta 2: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Install〜実行
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GLFWをインストール
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brwe &lt;span class="nb"&gt;install &lt;/span&gt;glfw
vim ~/.zshrc
&lt;span class="c"&gt;# 下記を追加&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/homebrew/include
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/homebrew/lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  リポジトリをclone
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/web3ten0/cpp-opengl-tetris.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  binディレクトリ作成、make、実行
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;cpp-opengl-tetris
&lt;span class="nb"&gt;mkdir &lt;/span&gt;bin
make
./bin/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cpp</category>
      <category>opengl</category>
      <category>glfw</category>
      <category>tetris</category>
    </item>
    <item>
      <title>M1 macのc++でGLFWを使ってみる</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Sun, 07 Aug 2022 17:13:52 +0000</pubDate>
      <link>https://dev.to/edo1z/m1-macnocdeglfwwoshi-tutemiru-c6k</link>
      <guid>https://dev.to/edo1z/m1-macnocdeglfwwoshi-tutemiru-c6k</guid>
      <description>&lt;p&gt;OpenGLについてまだ全然分かっていませんが、GLFWを使ってアニメーションを表示したいと思っています。とりあえず、M1 macのc++でウインドウを表示しました。&lt;/p&gt;

&lt;h2&gt;
  
  
  環境
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;
arm64
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; brew config
macOS: 12.5-arm64
Rosetta 2: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  GLFWをインストール
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;glfw
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; brew &lt;span class="nt"&gt;--prefix&lt;/span&gt; glfw
/opt/homebrew/opt/glfw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  コンパイル・実行してみるコード
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.glfw.org/documentation.html"&gt;ここ&lt;/a&gt;のExample code&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  インストールしただけだとエラーになる
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ g++ &lt;span class="nt"&gt;-o&lt;/span&gt; main main.cpp &lt;span class="nt"&gt;-lglfw&lt;/span&gt; &lt;span class="nt"&gt;-framework&lt;/span&gt; Cocoa &lt;span class="nt"&gt;-framework&lt;/span&gt; OpenGL &lt;span class="nt"&gt;-framework&lt;/span&gt; IOKit &lt;span class="nt"&gt;-framework&lt;/span&gt; CoreVideo
main.cpp:1:10: fatal error: &lt;span class="s1"&gt;'GLFW/glfw3.h'&lt;/span&gt; file not found
&lt;span class="c"&gt;#include &amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  CPATH, LIBRARY_PATHを環境変数に追加
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; vim ~/.zshrc
&lt;span class="c"&gt;# 下記を追加&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/homebrew/include
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/homebrew/lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  コンパイル・実行成功
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;コンパイル成功したけど、warningが沢山出る。これはAppleがOpenGLを基本廃止（非推奨）にしているかららしい。
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ g++ &lt;span class="nt"&gt;-o&lt;/span&gt; main main.cpp &lt;span class="nt"&gt;-lglfw&lt;/span&gt; &lt;span class="nt"&gt;-framework&lt;/span&gt; Cocoa &lt;span class="nt"&gt;-framework&lt;/span&gt; OpenGL &lt;span class="nt"&gt;-framework&lt;/span&gt; IOKit &lt;span class="nt"&gt;-framework&lt;/span&gt; CoreVideo
main.cpp:23:5: warning: &lt;span class="s1"&gt;'glClear'&lt;/span&gt; is deprecated: first deprecated &lt;span class="k"&gt;in &lt;/span&gt;macOS 10.14 - OpenGL API deprecated. &lt;span class="o"&gt;(&lt;/span&gt;Define GL_SILENCE_DEPRECATION to silence these warnings&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-Wdeprecated-declarations&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    glClear&lt;span class="o"&gt;(&lt;/span&gt;GL_COLOR_BUFFER_BIT&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers/gl.h:2394:13: note: &lt;span class="s1"&gt;'glClear'&lt;/span&gt; has been explicitly marked deprecated here
extern void glClear &lt;span class="o"&gt;(&lt;/span&gt;GLbitfield mask&lt;span class="o"&gt;)&lt;/span&gt; OPENGL_DEPRECATED&lt;span class="o"&gt;(&lt;/span&gt;10.0, 10.14&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  warningを非表示にしてみる
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;コードに下記を追加する。

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;#define GL_SILENCE_DEPRECATION&lt;/code&gt; によって、非表示になる。
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Makefileを作る
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;CPPFLAGS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt; src/includes
&lt;span class="nv"&gt;FRAMEWORKS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-framework&lt;/span&gt; Cocoa &lt;span class="nt"&gt;-framework&lt;/span&gt; OpenGL &lt;span class="nt"&gt;-framework&lt;/span&gt; IOKit &lt;span class="nt"&gt;-framework&lt;/span&gt; CoreVideo
&lt;span class="nv"&gt;LIBS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-lglfw&lt;/span&gt;

&lt;span class="nv"&gt;BUILD_DIR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; ./bin
&lt;span class="nv"&gt;SRC_DIRS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; ./src
&lt;span class="nv"&gt;SRCS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;shell&lt;/span&gt; find &lt;span class="nv"&gt;$(SRC_DIRS)&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.cpp&lt;span class="nf"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;OBJS&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;addprefix&lt;/span&gt; &lt;span class="nv"&gt;$(BUILD_DIR)&lt;/span&gt;/, &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;subst&lt;/span&gt; .cpp,.o, &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;notdir&lt;/span&gt; &lt;span class="nv"&gt;$(SRCS)&lt;/span&gt;&lt;span class="nf"&gt;)))&lt;/span&gt;

&lt;span class="nl"&gt;$(BUILD_DIR)/main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(OBJS)&lt;/span&gt;
    clang++ &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="nv"&gt;$(LIBS)&lt;/span&gt; &lt;span class="nv"&gt;$(FRAMEWORKS)&lt;/span&gt; &lt;span class="nv"&gt;$^&lt;/span&gt; 
&lt;span class="nl"&gt;$(BUILD_DIR)/%.o&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;src/%.cpp&lt;/span&gt;
    clang++ &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="nv"&gt;$(CPPFLAGS)&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt;

&lt;span class="nl"&gt;do&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;bin/main
&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; bin
    &lt;span class="nb"&gt;mkdir &lt;/span&gt;bin

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Debugできない
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;vimspectorで、&lt;code&gt;.vimspector.json&lt;/code&gt;を下記のように設定してみたけど、エラーになる。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-lglfw&lt;/code&gt;があるとエラーになるっぽい。
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CodeLLDB"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"adapter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CodeLLDB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"variables"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"BUILDME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"clang++ -o ${workspaceRoot}/bin/debug -g -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo ${workspaceRoot}/src/main.cpp"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"configuration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceRoot}/bin/debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"stdio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  青いウインドウを表示するコード
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#endif
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;key_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLFWwindow&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;scancode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;mods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;GLFW_KEY_ESCAPE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;GLFW_PRESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;glfwSetWindowShouldClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GLFW_TRUE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;GLFWwindow&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;glfwInit&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;glfwWindowHint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLFW_CONTEXT_VERSION_MAJOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;glfwWindowHint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLFW_CONTEXT_VERSION_MINOR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;glfwWindowHint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLFW_OPENGL_FORWARD_COMPAT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GL_TRUE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;glfwWindowHint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLFW_OPENGL_PROFILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GLFW_OPENGL_CORE_PROFILE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glfwCreateWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"failed to create window."&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;glfwTerminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"opened window"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;glfwSetKeyCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key_callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;glfwMakeContextCurrent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;glfwSwapInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;GLubyte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glGetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GL_RENDERER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;GLubyte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;glGetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GL_VERSION&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"Renderer: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"OpenGL version supported: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;glClearColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;glfwWindowShouldClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;glClear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GL_COLOR_BUFFER_BIT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glfwSwapBuffers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glfwPollEvents&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;glfwTerminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"closed window"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  リポジトリ
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/web3ten0/cpp-glfw-1"&gt;https://github.com/web3ten0/cpp-glfw-1&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  表示されるウインドウ
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M8iXmptK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iocg767bosq03rzrzsp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M8iXmptK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iocg767bosq03rzrzsp.png" alt="表示される青いウインドウ" width="685" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>glfw</category>
      <category>opengl</category>
      <category>gui</category>
    </item>
    <item>
      <title>NFTを作ってみた</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Tue, 14 Dec 2021 04:50:59 +0000</pubDate>
      <link>https://dev.to/edo1z/nftwozuo-tutemita-3l75</link>
      <guid>https://dev.to/edo1z/nftwozuo-tutemita-3l75</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.soliditylang.org/en/v0.8.10/"&gt;Solidity&lt;/a&gt;とTypeScriptと&lt;a href="https://hardhat.org/"&gt;Hardhat&lt;/a&gt;と&lt;a href="https://nft.storage/"&gt;nft.storage&lt;/a&gt;と&lt;a href="https://openzeppelin.com/contracts/"&gt;OpenZeppelin&lt;/a&gt;を使って、NFTを作成して、&lt;a href="https://opensea.io/"&gt;OpenSea&lt;/a&gt;で確認してみました。&lt;/p&gt;




&lt;h3&gt;
  
  
  ソースコード
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/web3ten0/hardhat1"&gt;https://github.com/web3ten0/hardhat1&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  .envの作成
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;.env&lt;/code&gt; をこのリポジトリのルートに作成して、下記を入力します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NFT_STORAGE_API_KEY = *****
METADATA_URI = https://ipfs.io/ipfs/*****/metadata.json
MATIC_TEST_URL=https://rpc-mumbai.maticvigil.com
PRIVATE_KEY_MATIC_TEST=*****
MINT_ADDRESS = 0x*****
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  画像とmetadata.jsonの作成・アップロード
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;hoge.jpgを作成して、このリポジトリのルートに置いておきます。&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nft.storage/"&gt;nft.storage&lt;/a&gt;にアカウントを作成して、API KEYを、&lt;code&gt;.env&lt;/code&gt; の &lt;code&gt;NFT_STORAGE_API_KEY&lt;/code&gt; に書きます。&lt;/li&gt;
&lt;li&gt;net.storageのgithubにnode.js用の&lt;a href="https://github.com/nftstorage/nft.storage/tree/main/packages/client/examples/node.js"&gt;サンプル&lt;/a&gt;がありますので、これを参考に、hoge.jpgをIPFSにアップして、metadata.jsonを作成し、URIを取得します。&lt;/li&gt;
&lt;li&gt;このリポジトリの &lt;code&gt;scripts/storage.ts&lt;/code&gt; は、上記を参考にしたコードです。下記を実行することで、&lt;code&gt;storage.ts&lt;/code&gt; が実行されます。
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npx hardhat run scripts/storage.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;実行後に、&lt;code&gt;https://ipfs.io/ipfs/****/metadata.json&lt;/code&gt; というURLが表示されますので、&lt;code&gt;.env&lt;/code&gt; の &lt;code&gt;METADATA_URI&lt;/code&gt; にそのURLをコピペします。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  NFTコントラクトの作成
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;コントラクトは、&lt;a href="https://docs.openzeppelin.com/contracts/4.x/erc721"&gt;ここ&lt;/a&gt;にあるコードをほぼコピペしました。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ERC721URIStorage&lt;/code&gt; だと、mint時にtokenURIを個別に指定できますので、ちょうどよいかなと思いました。&lt;/li&gt;
&lt;li&gt;このリポジトリの &lt;code&gt;contracts/NftStorage.sol&lt;/code&gt; になります。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  networkの設定
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;今回は、Polygonのテストネット（mumbai）にデプロイしてみました。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hardhat.config.ts&lt;/code&gt;でnetworkの設定ができます。Polygonの設定は&lt;a href="https://docs.polygon.technology/docs/develop/hardhat/"&gt;ここ&lt;/a&gt;が参考になります。&lt;/li&gt;
&lt;li&gt;URLとprivate keyが必要なので、&lt;code&gt;.env&lt;/code&gt;に書いておきます。

&lt;ul&gt;
&lt;li&gt;URLは、下記のように &lt;code&gt;MATIC_TEST_URL&lt;/code&gt; に書きます。&lt;/li&gt;
&lt;li&gt;プライベートキーはMetaMaskから取得したりして、下記のように、 &lt;code&gt;PRIVATE_KEY_MATIC_TEST&lt;/code&gt; に書きます。&lt;/li&gt;
&lt;li&gt;また、アカウントにはmumbaiのmaticが必要です。ない場合は、&lt;a href="https://faucet.polygon.technology/"&gt;ここ&lt;/a&gt;から貰えます。
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MATIC_TEST_URL=https://rpc-mumbai.maticvigil.com
PRIVATE_KEY_MATIC_TEST=*****
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  コントラクトのデプロイとmint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;mint時にNFTを送信するアドレスを、&lt;code&gt;.env&lt;/code&gt;の&lt;code&gt;MINT_ADDRESS&lt;/code&gt;に書きます。&lt;/li&gt;
&lt;li&gt;今回は、&lt;code&gt;test/deploy-nft-and-mint-test.ts&lt;/code&gt;でデプロイとmintを一緒に実行してみました。&lt;/li&gt;
&lt;li&gt;下記コマンドを実行すると、Polygonのmumbaiにコントラクトがデプロイされて、その後mintされます。
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; npx hardhat &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; mumbai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://testnets.opensea.io/"&gt;OpenSeaのテストネット&lt;/a&gt;でNFTを送信したアカウントでログインすると、NFTが表示されました。&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>solidity</category>
      <category>ethereum</category>
      <category>hardhat</category>
      <category>nft</category>
    </item>
    <item>
      <title>Solidityの数値の明示的な型変換の仕様をRustで試してみた</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Thu, 09 Dec 2021 06:40:09 +0000</pubDate>
      <link>https://dev.to/edo1z/soliditynoshu-zhi-noming-shi-de-naxing-bian-huan-noshi-yang-worustdeshi-sitemita-2h1i</link>
      <guid>https://dev.to/edo1z/soliditynoshu-zhi-noming-shi-de-naxing-bian-huan-noshi-yang-worustdeshi-sitemita-2h1i</guid>
      <description>&lt;p&gt;Solidityのドキュメントの&lt;a href="https://docs.soliditylang.org/en/v0.8.10/types.html#explicit-conversions"&gt;ここ&lt;/a&gt;に書いてある内容について、Rustも同じ仕様なのか？などを試してみました。&lt;/p&gt;

&lt;h3&gt;
  
  
  マイナスのintをuintに変換する
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;i8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a:{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  結果
&lt;/h4&gt;

&lt;p&gt;a:253&lt;/p&gt;

&lt;p&gt;Solidityと同じ結果でした。256を足すと答えが出るみたいになってる。&lt;/p&gt;




&lt;h3&gt;
  
  
  u32をu16に変換する
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x12345678&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b:{}({:#x?}) -&amp;gt; c:{}({:#x?})"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  結果
&lt;/h4&gt;

&lt;p&gt;b:305419896(0x12345678) -&amp;gt; c:22136(0x5678)&lt;/p&gt;

&lt;p&gt;Solidityと同じ結果でした。&lt;/p&gt;




&lt;h3&gt;
  
  
  u16をu32に変換する
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x00001234&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"u16:{:#x?} u32:{:#x?} u32:{:#x?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  結果
&lt;/h4&gt;

&lt;p&gt;u16:0x1234 u32:0x1234 u32:0x1234&lt;/p&gt;

&lt;p&gt;Solidityと同じ結果ってことかなと思いました。器が大きくなっただけなので、値自体は全く変わっていない、と認識しました。&lt;/p&gt;




&lt;h3&gt;
  
  
  bytes2からbytes1にする
&lt;/h3&gt;

&lt;p&gt;Solidityのドキュメントのこれです。&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yHPVGU2p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/401y12fm482zly5cpi0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yHPVGU2p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/401y12fm482zly5cpi0s.png" alt="Solidityのドキュメント" width="800" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;int, uintの場合は、容量を減らすと大きい数値がなくなり小さい方が残りますが、byte列の場合は、大きい方が残ると認識しました。&lt;/p&gt;

&lt;p&gt;Rustには、bytes2とかbytes1といった型は標準では多分なく、[u8; 2]みたいなu8型の配列やvectorで表すのかなと思います。下記は上記のSolidityの仕様と同じになるように、Rustでやってみたものです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x04030201&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="nf"&gt;.to_be_bytes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="nf"&gt;.clone_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_be_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}({:#x?}) -&amp;gt; {:?} -&amp;gt; {}({:#x?})"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  結果
&lt;/h4&gt;

&lt;p&gt;67305985(0x4030201) -&amp;gt; [4, 3, 2, 1] -&amp;gt; 1027(0x403)&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>rust</category>
    </item>
    <item>
      <title>TruffleでGoerliネットワークにコントラクトをデプロイする</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Thu, 02 Dec 2021 02:51:28 +0000</pubDate>
      <link>https://dev.to/edo1z/truffledegoerlinetutowakunikontorakutowodepuroisuru-plp</link>
      <guid>https://dev.to/edo1z/truffledegoerlinetutowakunikontorakutowodepuroisuru-plp</guid>
      <description>&lt;p&gt;TruffleでGethで接続しているGoerliネットワークにコントラクトをデプロイしてみます。&lt;/p&gt;

&lt;h3&gt;
  
  
  手順概要
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;GethでGoerliに接続する際に、HTTP APIを有効にする。

&lt;ul&gt;
&lt;li&gt;上記の際に、利用したいweb3コマンドのネームスペースを有効にする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;truffle-config.js&lt;/code&gt;にGoerli用のネットワーク設定を追加する。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;truffle migrate&lt;/code&gt;を&lt;code&gt;--network&lt;/code&gt;オプションでGoerli用ネットワークを指定して実行することで、デプロイが完了する。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. GethでGoerliに接続
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; geth &lt;span class="nt"&gt;--goerli&lt;/span&gt; &lt;span class="nt"&gt;--syncmode&lt;/span&gt; &lt;span class="s2"&gt;"light"&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt; &lt;span class="nt"&gt;--http&lt;/span&gt;.port 3334 &lt;span class="nt"&gt;--http&lt;/span&gt;.api personal,eth,web3,net &lt;span class="nt"&gt;--allow-insecure-unlock&lt;/span&gt; console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;上記実行後に、デプロイ時に利用するアカウントのロック解除をしておく。（以下はGethコンソールです）&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; personal.unlockAccount&lt;span class="o"&gt;(&lt;/span&gt;eth.accounts[0],&lt;span class="s1"&gt;'*******'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. truffle-config.jsでネットワークの設定
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;goerli&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3334&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.migrateの実行
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; truffle migrate &lt;span class="nt"&gt;--network&lt;/span&gt; goerli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ethereum</category>
      <category>truffle</category>
      <category>goerli</category>
      <category>geth</category>
    </item>
    <item>
      <title>Ethereumの超シンプルなコントラクトをgethコンソールからデプロイする</title>
      <dc:creator>edo1z</dc:creator>
      <pubDate>Mon, 29 Nov 2021 12:45:26 +0000</pubDate>
      <link>https://dev.to/edo1z/ethereumnochao-sinpurunakontorakutowogethkonsorukaradepuroisuru-54bk</link>
      <guid>https://dev.to/edo1z/ethereumnochao-sinpurunakontorakutowogethkonsorukaradepuroisuru-54bk</guid>
      <description>&lt;p&gt;下記の超シンプルなコントラクトをコンパイル、デプロイして、アクセスしてみます。Windows10のWSL2のUbuntu20.04でやっています。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: GPL-3.0
&lt;/span&gt;&lt;span class="k"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Hoge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;hoge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"HOGE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hoge&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;コンパイラは、solcを&lt;a href="https://docs.soliditylang.org/en/v0.8.10/installing-solidity.html#linux-packages"&gt;aptでインストール&lt;/a&gt;するか、&lt;a href="https://github.com/ethereum/solc-js"&gt;solc-js&lt;/a&gt;をnpmでインストールするかで、どちらでもコンパイルできました。以下はsolc-jsの場合です。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; solcjs &lt;span class="nt"&gt;--bin&lt;/span&gt; &lt;span class="nt"&gt;--abi&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; bin Hoge.sol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;コンパイルすると下記ファイルができます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ tree
&lt;span class="nb"&gt;.&lt;/span&gt;
├── Hoge.sol
└── bin
    ├── Hoge_sol_Hoge.abi
    └── Hoge_sol_Hoge.bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;デプロイするネットワークは、&lt;a href="https://goerli.net/"&gt;goerli&lt;/a&gt;にします。&lt;a href="https://faucet.goerli.mudit.blog/"&gt;ここ&lt;/a&gt;でgoerliで使えるETHをもらえます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; geth &lt;span class="nt"&gt;--goerli&lt;/span&gt; &lt;span class="nt"&gt;--syncmode&lt;/span&gt; &lt;span class="s2"&gt;"light"&lt;/span&gt; &lt;span class="nt"&gt;--verbosity&lt;/span&gt; 0 console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;上記を実行するとlightモードでgoerliに接続しつつ、gethコンソールが開きます。以下はgethコンソールでの作業です。利用するアカウントは、ETHを保有しています。アカウントのパスワードは &lt;code&gt;hoge&lt;/code&gt; です。&lt;/p&gt;

&lt;p&gt;まずは、コンパイルした &lt;code&gt;Hoge_sol_Hoge.bin&lt;/code&gt;と、&lt;code&gt;Hoge_sol_Hoge.abi&lt;/code&gt; の中身をgethコンソールの変数に入れておきます。binの中身の先頭に &lt;code&gt;0x&lt;/code&gt; をつける必要があります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bytecode &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0x608060405234801561001057600080fd5b50610182806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861004e565b604051610045919061012a565b60405180910390f35b606060006040518060400160405280600481526020017f484f47450000000000000000000000000000000000000000000000000000000081525090508091505090565b600081519050919050565b600082825260208201905092915050565b60005b838110156100cb5780820151818401526020810190506100b0565b838111156100da576000848401525b50505050565b6000601f19601f8301169050919050565b60006100fc82610091565b610106818561009c565b93506101168185602086016100ad565b61011f816100e0565b840191505092915050565b6000602082019050818103600083015261014481846100f1565b90509291505056fea264697066735822122097a132140711a9b641222ac8bc84bb5a671eb1c5c2b26d58c564036536ec0bba64736f6c63430008090033"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; abi &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"inputs"&lt;/span&gt;:[],&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"get"&lt;/span&gt;,&lt;span class="s2"&gt;"outputs"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"internalType"&lt;/span&gt;:&lt;span class="s2"&gt;"string"&lt;/span&gt;,&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;""&lt;/span&gt;,&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;,&lt;span class="s2"&gt;"stateMutability"&lt;/span&gt;:&lt;span class="s2"&gt;"pure"&lt;/span&gt;,&lt;span class="s2"&gt;"type"&lt;/span&gt;:&lt;span class="s2"&gt;"function"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;次に、アカウントのロックを解除して、コントラクトをデプロイします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; account &lt;span class="o"&gt;=&lt;/span&gt; eth.accounts[0]
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; personal.unlockAccount&lt;span class="o"&gt;(&lt;/span&gt;account, &lt;span class="s1"&gt;'hoge'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; params &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;from:account, data:bytecode, gas:500e3&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tx &lt;span class="o"&gt;=&lt;/span&gt; eth.sendTransaction&lt;span class="o"&gt;(&lt;/span&gt;params&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;トランザクションが反映されたかどうかは下記で確認できます。未反映の場合&lt;code&gt;null&lt;/code&gt;が返ります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; web3.eth.getTransactionReceipt&lt;span class="o"&gt;(&lt;/span&gt;tx&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;下記でコントラクトの関数を実行できます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; addr &lt;span class="o"&gt;=&lt;/span&gt; web3.eth.getTransactionReceipt&lt;span class="o"&gt;(&lt;/span&gt;tx&lt;span class="o"&gt;)&lt;/span&gt;.contractAddress
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Hoge &lt;span class="o"&gt;=&lt;/span&gt; web3.eth.contract&lt;span class="o"&gt;(&lt;/span&gt;abi&lt;span class="o"&gt;)&lt;/span&gt;.at&lt;span class="o"&gt;(&lt;/span&gt;addr&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; personal.unlockAccount&lt;span class="o"&gt;(&lt;/span&gt;account, &lt;span class="s1"&gt;'hoge'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; web3.eth.defaultAccount &lt;span class="o"&gt;=&lt;/span&gt; account
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Hoge.get.call&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s2"&gt;"HOGE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>solidity</category>
    </item>
  </channel>
</rss>
