【Rust】QRコードの生成

qrcode = “0.14.1”
image = “0.25.5”

use qrcode::QrCode;
use image::Luma;

fn main() {
    let code = QrCode::new(b"https://google.com").unwrap();
    let image = code.render::<Luma<u8>>().build();

    image.save("./data/qrcode.png").unwrap();

    let string = code.render()
        .light_color(' ')
        .dark_color('#')
        .build();
    println!("{}", string);
}

うーん、なるほど…

【Rust】OpenAIの画像生成AIを使ってみる

open ai reference
https://platform.openai.com/docs/api-reference/images/create

なんじゃこりゃ…

use std::io::{stdout, Write};
use curl::easy::{Easy, List};
use dotenv::dotenv;
use std::env;


fn main() {
    let _ = dotenv();
    let auth = format!("Authorization: Bearer {}", &env::var("OPENAI_API_KEY").unwrap());
    let mut list = List::new();
    list.append("Content-Type: application/json").unwrap();
    list.append(&auth).unwrap();
    
    let mut handle = Easy::new();
    handle.url("https://api.openai.com/v1/images/generations").unwrap();
    handle.post(true).unwrap();
    handle.http_headers(list).unwrap();

    let post_field_bytes = "{ \"model\": \"dall-e-3\", \"prompt\": \"A cute baby sea otter\", \"n\": 1, \"size\": \"1024x1024\"}".as_bytes();
    handle.post_fields_copy(post_field_bytes).unwrap();

    handle.write_function(|data| {
    stdout().write_all(data).unwrap();
    Ok(data.len())
    }).unwrap();

    handle.perform().unwrap();

}

Compiling sample v0.1.0 (/home/vagrant/dev/rust/sample)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.58s
Running `target/debug/sample`
{
“created”: 1738034805,
“data”: [
{
“revised_prompt”: “Imagine a charming depiction of a baby sea otter. This adorable little creature is floating on its back in the gentle waves of a clear blue ocean. Its fur, a shade of rich brown, is slick and slightly wet from its playful activities in the water. The otter’s bright, curious eyes are looking directly towards us, as if inviting us to join the fun. It is holding a small, smooth pebble with its tiny paws, perhaps preparing to break open a shell for a feast. The entire image exudes a sense of playfulness, innocence and natural beauty.”,
“url”: “https://oaidalleapiprodscus.blob.core.windows.net/private/org-wo6kkwujqXYOYKEKz5X1nc60/user-JNvegCxXc2nlYJGCjwPgwcv7/img-Z6WR4EMZFstjPwV7BQriTyyf.png?st=2025-01-28T02%3A26%3A45Z&se=2025-01-28T04%3A26%3A45Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2025-01-28T00%3A53%3A13Z&ske=2025-01-29T00%3A53%3A13Z&sks=b&skv=2024-08-04&sig=V2MXStLlOGdaaB7OOT65JzvSFLRA9zOMHOLN8UPOg1o%3D”
}
]
}

面白いんだけど、サービスとして提供するのは抵抗あるな…

【Rust】OpenAIのAPIを使ってみる

APIキーをenvファイルに設定しなければならないので、OSSとして使うのは無理があるな…

use dotenv::dotenv;
use std::env;
use openai_api_rust::*;
use openai_api_rust::chat::*;
use openai_api_rust::completions::*;

fn main() {
    let _ = dotenv();
    let auth = Auth::new(&env::var("OPENAI_API_KEY").unwrap());
    let openai = OpenAI::new(auth, "https://api.openai.com/v1/");
    let body = ChatBody {
        model: "gpt-3.5-turbo".to_string(),
        max_tokens: Some(100),
        temperature: Some(0_f32),
        top_p: Some(0_f32),
        n: Some(2),
        stream: Some(false),
        stop: None,
        presence_penalty: None,
        frequency_penalty: None,
        logit_bias: None,
        user: None,
        messages: vec![Message { role: Role::User, content: "有名なキャラクターは?".to_string() }],
    };
    let rs = openai.chat_completion_create(&body);
    let choice = rs.unwrap().choices;
    let message = &choice[0].message.as_ref().unwrap();
    println!{"{}", message.content};
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.14s
Running `target/debug/sample`
有名なキャラクターには、以下のようなものがあります。

– ミッキーマウス(ディズニーキャラクター)
– マリオ(任天堂のゲーム「スーパーマリオブラザーズ」の主人公)
– ピカチュウ(ポケモンの一匹)

【Rust】envファイルの設定方法

cargo.tomlと同じディレクトリに.envを作成します。

.env

APP_VERSION=1.0.0
APP_PROD=false
dotenv="0.15.0"
use dotenv::dotenv;
use std::env;

fn main() {
    dotenv();
    println!("{}", env::var("APP_VERSION").unwrap());
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/sample`
1.0.0

なるほどねー

【Rust】二分探索(binary search)

fn main() {
    let data = vec![10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
    let target = 50;
    binary_search(data, target);
    
}

fn binary_search(data: Vec<u32>, target: u32) {
    let mut left = 0;
    let mut right = data.len() - 1;
    
    while left <= right {
        let mid = (left + right) / 2;
        if data[mid] == target {
            println!("ターゲットは要素の[{}]です。", mid);
            break;
        } else if data[mid] < target {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/rust`
ターゲットは要素の[4]です。

これは凄い面白いなあ

【Rust】線形探索

fn main() {
    let target = 40;
    let mut flg = format!("{}{}", target, "はデータの中にありません");
    let data = [50, 30, 90, 10, 20, 70, 60, 40, 80];
    for d in data {
        if d == 40 {
            flg = format!("{}{}", target, "はデータの中にあります!");
        }
    }
    println!("{}", flg);
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.56s
Running `target/debug/rust`
40はデータの中にあります!

### 関数を定義
配列だと、data: [u32; 10] というように要素数を指定しなければならないので、Vectorの方が使い勝手が良い。

fn main() {
    let data = vec![50, 30, 90, 10, 20, 70, 60, 40, 80, 55];
    let target = 40;
    linear_search(data, target);
    
}

fn linear_search(data: Vec<u32>, target: u32) {
    let mut flg = format!("{}{}", target, "はデータの中にありません");
    for d in data {
        if d == 40 {
            flg = format!("{}{}", target, "はデータの中にあります!");
        }
    }
    println!("{}", flg);
}

【Rust】fibonacci関数にcoroutineを組み合わせたい

関数の呼び出しの中でcoroutineを使用する。返り値にimpl Coroutineと書くと、期待通りの挙動になる。

#![feature(coroutines)]
#![feature(coroutine_trait)]
#![feature(stmt_expr_attributes)]

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn test() -> impl Coroutine{
    let mut coroutine = #[coroutine] || {
        println!("2");
        yield;
        println!("4");
    };
    return coroutine
}

fn main() {
    
    let mut coroutine = test();

    println!("1");
    Pin::new(&mut coroutine).resume(());
    println!("3");
    Pin::new(&mut coroutine).resume(());
    println!("5");
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/parallel`
1
2
3
4
5

fn fibonacci(n: u32)-> u32{
    if(n == 1) || (n == 2) {
        return 1;
    }
    return coroutines::spawn(move ||fibonacci(n - 2)).join().unwrap() + coroutines::spawn(move ||fibonacci(n - 1)).join().unwrap();
}

fn main() {
    println!("{}", fibonacci(8));
}

error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL=”C” PATH=”/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/bin:/home/vagrant/.vscode-server/cli/servers/Stable-fee1edb8d6d72a0ddff41e5f71a671c23ed924b9/server/bin/remote-cli:/home/vagrant/.local/bin:/home/vagrant/.cargo/bin:/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin” VSLANG=”1033″ “cc” “/tmp/rustclduixt/symbols.o” “<71 object files omitted>” “-Wl,–as-needed” “-Wl,-Bstatic” “/home/vagrant/dev/rust/parallel/target/debug/deps/{libcoroutines-73d67594ef572d45.rlib,libspin-b921464275125a8a.rlib}” “/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/{libstd-37c91c156f70721a.rlib,libpanic_unwind-091ab8f68cc61686.rlib,libobject-e2f7a15061957456.rlib,libmemchr-c98c798b414d6437.rlib,libaddr2line-9aff78f201895d3e.rlib,libgimli-136ec4cd87684724.rlib,librustc_demangle-de97401acb73e7bd.rlib,libstd_detect-c05658b587ae52a4.rlib,libhashbrown-64cb6e685fd4789d.rlib,librustc_std_workspace_alloc-83e0c642422571d6.rlib,libminiz_oxide-37d00f2abcaa32e0.rlib,libadler2-4baacb3803247097.rlib,libunwind-7fc1e71b6d069b5b.rlib,libcfg_if-96e210777df10d05.rlib,liblibc-910d42f9f92e088d.rlib,liballoc-8d48e7538af467a9.rlib,librustc_std_workspace_core-1afa26d7618dba03.rlib,libcore-a40bbbb3fb06de3c.rlib,libcompiler_builtins-2b4a3d060745bb29.rlib}” “-Wl,-Bdynamic” “-lunblock_hook” “-lgcc_s” “-lutil” “-lrt” “-lpthread” “-lm” “-ldl” “-lc” “-Wl,–eh-frame-hdr” “-Wl,-z,noexecstack” “-L” “/home/vagrant/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib” “-o” “/home/vagrant/dev/rust/parallel/target/debug/deps/parallel-9e5acb293a2c78f7” “-Wl,–gc-sections” “-pie” “-Wl,-z,relro,-z,now” “-nodefaultlibs”
= note: some arguments are omitted. use `–verbose` to show all linker arguments
= note: /usr/bin/ld: cannot find -lunblock_hook: No such file or directory
collect2: error: ld returned 1 exit status

うーん、わからん…

【Rust】coroutineを使いたい

#![feature(coroutines)]
#![feature(coroutine_trait)]
#![feature(stmt_expr_attributes)]

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn main() {
    let mut coroutine = #[coroutine] || {
        yield 1;
        "foo"
    };

    match Pin::new(&mut coroutine).resume(()) {
        CoroutineState::Yielded(1) => {
            println!("yielded test");
        }
        _ => panic!("unexpected return from resume"),
    }
    match Pin::new(&mut coroutine).resume(()) {
        CoroutineState::Complete("foo") => {
            println!("foo test");
        }
        _ => panic!("unexpected return from resume"),
    }
}

error[E0554]: `#![feature]` may not be used on the stable release channel

$ rustup install nightly
$ cargo +nightly run
Compiling parallel v0.1.0 (/home/vagrant/dev/rust/parallel)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s
Running `target/debug/parallel`
yielded test
foo test

use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;

fn main() {
    let mut coroutine = #[coroutine] || {
        println!("2");
        yield;
        println!("4");
    };

    println!("1");
    Pin::new(&mut coroutine).resume(());
    println!("3");
    Pin::new(&mut coroutine).resume(());
    println!("5");
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s
Running `target/debug/parallel`
1
2
3
4
5

Pin::new(&mut coroutine).resume(());で一旦停止するのか…

【Rust】フィボナッチ数列

フィボナッチは再起的に計算を行う。

6 の場合は、
6 -> (4,5)
4 -> (2,3)
5 -> (3,4)
2 -> 【1】
3 -> (1, 2) -> 【1】【1】

fn fibonacci(n: u32)-> u32{
    if(n == 1) || (n == 2) {
        return 1;
    }
    return fibonacci(n - 2) + fibonacci(n - 1);
}


fn main() {
    println!("{}", fibonacci(6));
}

Compiling rust v0.1.0 (/home/vagrant/dev/algorithm/rust)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
Running `target/debug/rust`
8

8の時は21, 10は55となる。
なんか不思議な感じがする。

【Rust】素数の判定

まず、prime(平方根)を計算する。sqrt()はf64にする必要がある。

fn main() {
    let x = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    for i in x {
        let y = (i as f64).sqrt();
        println!("{}", y);
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.29s
Running `target/debug/rust`
1
1.4142135623730951
1.7320508075688772
2
2.23606797749979
2.449489742783178
2.6457513110645907
2.8284271247461903
3

nが、2から平方根までの値で割り切れれば、素数ではない

fn main() {
    let x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
    for i in x {
        let mut flag = true;
        let prime = (i as f64).sqrt();
        if prime >= 2.0 {
            for j in 2..((prime + 1.0) as u32){
                if i % j == 0 {
                    flag = false;
                    break;
                }
            }
        }
        if flag == true {
            println!("{}は素数です", i);}
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
Running `target/debug/rust`
1は素数です
2は素数です
3は素数です
5は素数です
7は素数です
11は素数です
13は素数です

floatへの変換を書かなければならない分、コードが冗長になるが、もう少しエレガントに書きたいものだ。○○か否かはTrue or Falseが書きやすい。