icon

nazo6.dev

一覧に戻る
2021/12/27 2023/10/20 5 min read

Rust


#(2021-12-27)

気づきとかいろいろ

#エラーハンドリング (2021-12-27)

#Result<T, E>Option<T>がある (2021-12-27)

  • okok_or(T)で相互変換可能
  • また下のanyhowで提供されているanyhow::contextを使うことでOptionをResultにできるみたい

#汎用的なエラーはResult<T, Box<dyn std::error::Error>> (2021-12-27)

  • Boxはヒープ領域
    • ? 演算子を使ったときにBox::newがいらないのはなぜ?
  • dyn Errorの意味はあとで調べる

#と思ったけどanyhowがよさそう?

  • anyhow::Result<T>で上とほぼ同じことができる
  • さらにanyhow::anyhow!マクロで手軽にエラーメッセージを作れる。これは便利

#? 演算子 (2021-12-27)

  • ResultOptionを返す関数の中で使うとNoneErrのときに早期リターンできる
  • 関数をreturnするのでブロックの値を返すためには使えない(tauriのcommandsはserdeでエンコードできるものでないといけないから恐らく上のanyhowは使えない?) 例: これはaにResultが入るわけではない
let a = {
   hoge()?
}
  • なので即時関数を使う 参照:
let a: Result<String, Box<dyn Error>> = ||{
  hoge()?
}

#非同期 (2021-12-27)

#(2021-12-27)

  • 非同期関数はasync fn(T) -> Uと宣言する。
    • jsのPromiseみたいにPromise<T>と包むのではなく非同期な返り値をそのまま書くみたい
  • f().awaitで呼び出す
  • Futureがなんなのかよくわかんない

#ライブラリ (2021-12-27)

  • async構文自体は言語仕様だがそれを実装するライブラリが必要?よくわかってない
  • async-stdというものもあったがやっぱりデファクトスタンダードはtokioだと思われる

#クロージャ (2021-12-27)

  • async || {}という書きかたはunstableらしい。
    • なので|| async {}と書く
    • 即時関数なら(|| async{})().await

#reqwest (2021-12-27)

  • 高レベルなHTTPクライアント

#ファイルに保存する方法

use futures_util::StreamExt;
use tokio::io::AsyncWriteExt;
 
let file_dir = path.parent().ok_or(anyhow!("Invalid path"))?;
if !file_dir.is_dir() {
    create_dir_all(file_dir).await?;
}
let mut file = tokio::fs::File::create(&path).await?;
while let Some(item) = stream.next().await {
    file.write_all_buf(&mut item?).await?;
}
let path_str = path.to_str().ok_or(anyhow!("?"))?;
Ok(path_str.to_string())

参考: https://github.com/seanmonstar/reqwest/issues/1266#issue-875945198

  • streamがよくわかってないけどとりあえずこれでいける
    • futures_utilはなんだろう
  • 最後のところをOk(path_str)に変えたらなにかエラーがでた
    • おそらくライフタイム関連の何かだと思うが・・・今は解決できないので保留

#非同期handler関数を引数として受けとりさらにそれをtokioでspawnさせる (2022-03-20)

このクレートをパク…参考にした

handler.rs
use async_trait::async_trait;
use std::future::Future;
use std::pin::Pin;
 
use crate::error::Error;
 
#[async_trait]
pub trait Handler: Send + Sync + 'static {
    #[must_use]
    async fn apply(self: Pin<&Self>, request: [request]) -> Result<[response], Error>;
}
 
#[async_trait]
impl<F, Fut> Handler for F
where
    F: Fn(String) -> Fut + Sync + Send + 'static,
    Fut: Future<Output = Candidates> + Send + 'static,
{
    async fn apply(self: Pin<&Self>, request: [request]) -> Result<[response], Error> {
        Ok(self(request).await)
    }
}

使用側:

main.rs
#[tokio::main]
async fn main() {
    let server = Server::new(handler);
    let result = server.start().await;
}
async fn handler(request: [request]) -> [response] {
   [response]
}
 
pub struct Server {
    handler: Arc<Pin<Box<dyn Handler>>>,
}
 
impl Server {
    pub fn new<H: Handler>(handler: H) -> Self {
        Server {
          handler
        }
    }
    pub async fn start(self) -> Result<(), Error> {
        let listener = TcpListener::bind((self.address, self.port)).await?;
        loop {
            let (stream, socket) = listener.accept().await?;
 
            let getter = Arc::clone(&self.candidates_getter);
            tokio::spawn(async move {
                info!("Socket connected: {}:{}", socket.ip(), socket.port());
                Self::process(stream, getter).await
            });
        }
    }
    async fn process(
        stream: TcpStream,
        handler: Arc<Pin<Box<dyn Handler>>>,
    ) -> Result<(), Error> {
        let handler_resut = (*handler).as_ref().apply([handler_prameters]).await;
    }
}

正直なんでこれで動くかはよくわかってない Pinに対する知識が足りてない

Share this article:
一覧に戻る

関連記事

2024/3/23

#tech/lang/rust#hardware/keyboard/keyball
blog

RustでKeyballのファームウェアを書きたい話

KeyballのファームウェアはQMKを使ったC言語のものになっています。ですがやはりRust、使いたいですよね?

Read Article

2023/5/26

#tech/lang/rust#tech/database
memo

RustでSQLからコードを生成するcornucopiaについて

SQLからRustのコードを生成して安全にデータベース操作ができる。恐らくGoのsqlcと同じ感じなんだと思う。

Read Article

2023/11/15

#tech/lang/rust
memo

Rustでジョブキュー的なもの

実行するコマンド(EnqueueかClear)をチャネルで受け取る

Read Article

2025/12/13

2025/12/14

#tech/lang/rust
blog

RustでデスクトップGUI - gpui入門 Part1 (gpuiの仕組み・状態管理の基礎編)

gpui解説記事のPart1。gpuiのレンダリング方法や状態管理について、実際のソースを見ながら詳しく解説します。

Read Article

2024/4/26

2024/5/22

#tech/lang/rust#hardware/keyboard/keyball
blog

RustとEmbassyでKeyballのファームウェアを作った

以前RustでKeyballのファームウェアを書きたい話で、ATMega32U4向けのファームウェアの作成をRustで試みたという話を書きましたが、結論から言うとこれは諦めてProMicro RP2040向けのファームウェアをRustで書くことにしました。

Read Article

2023/8/27

#tech/lang/rust
memo

Rustのserde_jsonでエラーの発生箇所を知る方法

serde_jsonではパースエラー発生時にどのプロパティでエラーが発生したのかわからない

Read Article

2023/6/27

#tech/lang/rust
memo

Rustのtargetフォルダを軽くする

cargo-sweepを使う

Read Article

2022/2/13

#tech/lang/rust
memo

Rustアプリにwasmerを埋め込む

dioxusを使ってwebでもdesktopでも動くアプリを作りたい

Read Article

2025/3/29

#tech/lang/rust
memo

Rustアプリのメモリ使用量を調査する

主にstatic領域のメモリ使用量を調査するのに有益。embassyの独立したタスクなどのサイズが見れる。

Read Article

2023/9/10

2023/12/18

#tech/lang/rust
blog

SerdeのDeserializerを実装する(Part1)

Serdeで任意の形式のファイルなどをデシリアライズする際にはDeserializerを書く必要があります。この記事では基本的なDeserializerの書き方を解説します。 正直自分もあまり理解していない部分が多々あるのですが世に出ている情報が少ないので書くことにしました。

Read Article

2023/12/18

2023/12/19

#tech/lang/rust
blog

SerdeのDeserializerを実装する(Part2 JSON編)

この記事はRust Advent Calendar 2023 シリーズ3の19日目の記事です。

Read Article

2024/5/24

#hardware/keyboard#tech/lang/rust
blog

USB HIDキーボードでメディアキーを操作する方法

USB HIDでは0x80がVolume Up、0x81がVolume Downに割り当てられており、さらに0xEDや0xEEでもVolume UpやDownができそうですが、実はこれらは全て動きません(Windowsでは)。

Read Article

2023/9/1

#tech/lang/rust
blog

prisma-client-rust入門

prisma-client-rustはJavascript向けのORMであるprismaをRustから使えるようにしたものです。実はprismaのコア部分はRustで書かれているためこういうものも作りやすかったんじゃないかと思います。

Read Article

2021/12/25

#tech/lang/rust
memo

tauriでWindows上でproductionビルドでのみ画像が表示されない(fetchエラーが発生する)

誰の役にも立たない気がするけどハマったのでメモ

Read Article

2023/11/18

#tech/lang/rust
blog

tokioで作ったサーバーをdockerで起動すると終了が遅くなるときの対処法

axumなどを作ってRustでサーバーを作るとdocker compose stopなどが微妙に遅くてイライラだったのでそれを解決する方法です。

Read Article

2025/4/9

2025/11/5

#tech/lang/rust
blog

「Rustが嫌いです。」の感想

https://zenn.dev/miguel/articles/f052de93fc9980

Read Article

© 2025 nazo6. All rights reserved.