Pythonにおけるpip、Rubyにおけるgemみたいなのが、Rustにもあります。
今回はactix-webというパッケージを使ってWEB鯖をつくってみます。
実際のところ
とりあえずシンプルに
パッケージ導入
tomlファイルというのがありましたが、こいつを弄ると入る様子
[package] name = "grrs" # cargo newで指定した名前 version = "0.1.0" # 自分で定義するバージョン情報 edition = "2021" # Rustのバージョン。特に強い理由がない場合、2024年時点では2021が推奨 [dependencies] actix-web = "4.4"
** スクリプト
// Actix Web - 高性能な非同期Webフレームワーク use actix_web::{web, App, HttpResponse, HttpServer}; #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new().route("/", web::get().to(|| async { HttpResponse::Ok().body("Hello world!") })) }) .bind("127.0.0.1:8080")? .run() .await }
実行
$ cargo run
で初回実行すると、必要なパッケージを導入してくれます。
platformIOみたいにパッケージを入れるというより、ビルドすると時に必要なパッケージを入れる様子。
ちょっとした機能を追加し複数パッケージでやる
toml
[dependencies] actix-web = "4.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"
スクリプト
use actix_web::{get, web, App, HttpResponse, HttpServer}; use serde::{Deserialize, Serialize}; #[derive(Deserialize)] struct TempQuery { value: f64, unit: String, // "C" for Celsius, "F" for Fahrenheit } #[derive(Serialize)] struct TempResult { input_value: f64, input_unit: String, output_value: f64, output_unit: String, formatted_result: String, } fn celsius_to_fahrenheit(celsius: f64) -> f64 { (celsius * 9.0 / 5.0) + 32.0 } fn fahrenheit_to_celsius(fahrenheit: f64) -> f64 { (fahrenheit - 32.0) * 5.0 / 9.0 } #[get("/")] async fn hello() -> HttpResponse { // HTMLフォームを返す let html = r#" <!DOCTYPE html> <html> <head> <title>Temperature Converter</title> </head> <body> <h1>Temperature Converter</h1> <form action="/convert" method="get"> <input type="number" step="0.1" name="value" required> <select name="unit"> <option value="C">Celsius</option> <option value="F">Fahrenheit</option> </select> <input type="submit" value="Convert"> </form> </body> </html> "#; HttpResponse::Ok() .content_type("text/html") .body(html) } #[get("/convert")] async fn convert(query: web::Query<TempQuery>) -> HttpResponse { let result = match query.unit.as_str() { "C" => { let fahrenheit = celsius_to_fahrenheit(query.value); TempResult { input_value: query.value, input_unit: "C".to_string(), output_value: fahrenheit, output_unit: "F".to_string(), formatted_result: format!("{:.1} °C = {:.1} °F", query.value, fahrenheit), } }, "F" => { let celsius = fahrenheit_to_celsius(query.value); TempResult { input_value: query.value, input_unit: "F".to_string(), output_value: celsius, output_unit: "C".to_string(), formatted_result: format!("{:.1} °F = {:.1} °C", query.value, celsius), } }, _ => return HttpResponse::BadRequest().json(serde_json::json!({ "error": "Invalid unit specified" })), }; HttpResponse::Ok() .content_type("application/json") .json(result) } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service(hello) .service(convert) }) .bind("127.0.0.1:8080")? .run() .await }
実行
ためしに120で摂氏から華氏変換してみると、こんな感じでJSONがでてきます。
{ "input_value": 120, "input_unit": "C", "output_value": 248, "output_unit": "F", "formatted_result": "120.0 °C = 248.0 °F" }