| use axum::{ |
| response::Html as AxumHtml, |
| routing::get, |
| Router, |
| }; |
| use std::env; |
|
|
| #[tokio::main] |
| async fn main() { |
| let app = Router::new() |
| .route("/", get(index_handler)) |
| .route("/health", get(|| async { "ok" })); |
|
|
| let port = env::var("PORT").unwrap_or_else(|_| "7860".to_string()); |
| let addr = format!("0.0.0.0:{}", port); |
| |
| let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); |
| axum::serve(listener, app).await.unwrap(); |
| } |
|
|
| async fn index_handler() -> AxumHtml<String> { |
| |
| let products = vec![ |
| ("Rust Ferris", "29.99 $", "https://rustacean.net/assets/rustacean-flat-gesture.png", "Мягкий краб Феррис."), |
| ("Turbo Engine", "49.99 $", "https://foundation.rust-lang.org/img/rust-logo-blk.svg", "Максимальная скорость."), |
| ("Safe Shield", "15.00 $", "https://www.rust-lang.org/static/images/rust-logo-blk.svg", "Безопасность памяти."), |
| ]; |
|
|
| let mut cards = String::new(); |
| for p in products { |
| cards.push_str(&format!( |
| r#"<div class="bg-white rounded-xl shadow-md overflow-hidden border border-gray-100 p-4"> |
| <img src="{}" class="h-40 w-full object-contain mb-4"> |
| <h3 class="text-lg font-bold">{}</h3> |
| <p class="text-sm text-gray-500 mb-4">{}</p> |
| <div class="flex justify-between items-center"> |
| <span class="text-orange-600 font-bold text-xl">{}</span> |
| <button class="bg-black text-white px-3 py-1 rounded shadow hover:bg-orange-600 transition">Купить</button> |
| </div> |
| </div>"#, |
| p.2, p.0, p.3, p.1 |
| )); |
| } |
|
|
| let html = format!( |
| r#"<!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="UTF-8"> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <title>Rust Store</title> |
| </head> |
| <body class="bg-gray-50 font-sans"> |
| <nav class="bg-white shadow-sm p-4 sticky top-0 z-10"> |
| <div class="max-w-6xl mx-auto flex justify-between items-center"> |
| <h1 class="text-2xl font-black text-orange-600 tracking-tighter">RUST SHOP</h1> |
| <div class="space-x-4 text-gray-600 font-medium"> |
| <a href="#">Каталог</a> |
| <a href="#">Доставка</a> |
| </div> |
| </div> |
| </nav> |
| <main class="max-w-6xl mx-auto p-8"> |
| <div class="mb-12 text-center"> |
| <h2 class="text-4xl font-extrabold text-gray-900 mb-2">Надежный мерч на Rust</h2> |
| <p class="text-gray-500">Скомпилировано для вашего комфорта</p> |
| </div> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-8"> |
| {} |
| </div> |
| </main> |
| <footer class="text-center py-10 text-gray-400 text-sm border-t mt-10"> |
| © 2026 Rust Axum Store | Hugging Face Spaces |
| </footer> |
| </body> |
| </html>"#, |
| cards |
| ); |
|
|
| AxumHtml(html) |
| } |