Kgshop commited on
Commit
9853ca3
·
verified ·
1 Parent(s): e704ac3

Update src/main.rs

Browse files
Files changed (1) hide show
  1. src/main.rs +138 -19
src/main.rs CHANGED
@@ -1,37 +1,156 @@
1
- use axum::{routing::get, Router};
 
 
 
 
 
 
2
  use std::env;
3
  use tracing::{info, error};
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  #[tokio::main]
6
  async fn main() {
7
- // Включаем нормальное логирование
8
  tracing_subscriber::fmt()
9
  .with_max_level(tracing::Level::INFO)
10
  .init();
11
 
12
- info!("🚀 Приложение запускается...");
13
 
14
  let app = Router::new()
15
- .route("/", get(|| async {
16
- info!("✅ Получен запрос на /");
17
- "✅ Rust успешно работает на HF Spaces!\n\nТвой магазин на Rust готов к портированию."
18
- }))
19
  .route("/health", get(|| async { "ok" }));
20
 
21
  let port = env::var("PORT").unwrap_or_else(|_| "7860".to_string());
22
  let addr = format!("0.0.0.0:{}", port);
23
 
24
- info!("📡 Сервер слушает на {}", addr);
25
-
26
- match tokio::net::TcpListener::bind(&addr).await {
27
- Ok(listener) => {
28
- info!("✅ Сервер успешно запущен!");
29
- if let Err(e) = axum::serve(listener, app).await {
30
- error!("❌ Сервер упал: {}", e);
31
- }
32
- }
33
- Err(e) => {
34
- error!("❌ Не удалось запустить сервер на {}: {}", addr, e);
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
 
1
+ use ax_utils::Html; // Для возврата HTML
2
+ use axum::{
3
+ response::Html as AxumHtml,
4
+ routing::get,
5
+ Router,
6
+ };
7
+ use serde::Serialize;
8
  use std::env;
9
  use tracing::{info, error};
10
 
11
+ // Структура нашего товара
12
+ #[derive(Serialize, Clone)]
13
+ struct Product {
14
+ id: u32,
15
+ name: &'static str,
16
+ price: &'static str,
17
+ image: &'static str,
18
+ description: &'static str,
19
+ }
20
+
21
+ // Наш "база данных" в памяти
22
+ const PRODUCTS: &[Product] = &[
23
+ Product {
24
+ id: 1,
25
+ name: "Rust Ferris Plush",
26
+ price: "29.99 $",
27
+ image: "https://rustacean.net/assets/rustacean-flat-gesture.png",
28
+ description: "Мягкий и уютный Феррис для вашего рабочего стола.",
29
+ },
30
+ Product {
31
+ id: 2,
32
+ name: "Turbo Gear",
33
+ price: "49.99 $",
34
+ image: "https://foundation.rust-lang.org/img/rust-logo-blk.svg",
35
+ description: "Шестеренка, которая заставляет всё работать максимально быстро.",
36
+ },
37
+ Product {
38
+ id: 3,
39
+ name: "Memory Safe Shield",
40
+ price: "15.00 $",
41
+ image: "https://www.rust-lang.org/static/images/rust-logo-blk.svg",
42
+ description: "Защита от сегфолтов и утечек памяти в реальной жизни.",
43
+ },
44
+ ];
45
+
46
  #[tokio::main]
47
  async fn main() {
 
48
  tracing_subscriber::fmt()
49
  .with_max_level(tracing::Level::INFO)
50
  .init();
51
 
52
+ info!("🚀 Запуск Rust-каталога...");
53
 
54
  let app = Router::new()
55
+ .route("/", get(index_handler))
 
 
 
56
  .route("/health", get(|| async { "ok" }));
57
 
58
  let port = env::var("PORT").unwrap_or_else(|_| "7860".to_string());
59
  let addr = format!("0.0.0.0:{}", port);
60
 
61
+ info!("📡 Сервер на {}", addr);
62
+
63
+ let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
64
+ axum::serve(listener, app).await.unwrap();
65
+ }
66
+
67
+ // Обработчик главной страницы
68
+ async fn index_handler() -> AxumHtml<String> {
69
+ info!("✅ Рендеринг витрины");
70
+
71
+ let mut cards_html = String::new();
72
+
73
+ for p in PRODUCTS {
74
+ cards_html.push_str(&format!(
75
+ r#"
76
+ <div class="bg-white rounded-2xl shadow-sm hover:shadow-xl transition-shadow duration-300 overflow-hidden border border-gray-100">
77
+ <div class="h-48 bg-gray-50 flex items-center justify-center p-6">
78
+ <img src="{image}" alt="{name}" class="max-h-full object-contain">
79
+ </div>
80
+ <div class="p-6">
81
+ <h3 class="text-lg font-bold text-gray-800">{name}</h3>
82
+ <p class="text-sm text-gray-500 mt-2">{description}</p>
83
+ <div class="flex items-center justify-between mt-6">
84
+ <span class="text-xl font-extrabold text-orange-600">{price}</span>
85
+ <button class="bg-gray-900 text-white px-4 py-2 rounded-lg hover:bg-orange-600 transition-colors">
86
+ В корзину
87
+ </button>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ "#,
92
+ image = p.image,
93
+ name = p.name,
94
+ description = p.description,
95
+ price = p.price
96
+ ));
97
  }
98
+
99
+ AxumHtml(format!(
100
+ r#"
101
+ <!DOCTYPE html>
102
+ <html lang="ru">
103
+ <head>
104
+ <meta charset="UTF-8">
105
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
106
+ <script src="https://cdn.tailwindcss.com"></script>
107
+ <title>Rust Shop Labs</title>
108
+ <style>
109
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800&display=swap');
110
+ body {{ font-family: 'Inter', sans-serif; }}
111
+ </style>
112
+ </head>
113
+ <body class="bg-gray-50 text-gray-900">
114
+ <!-- Header -->
115
+ <header class="bg-white border-b border-gray-200 sticky top-0 z-50">
116
+ <div class="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
117
+ <div class="flex items-center space-x-2">
118
+ <div class="w-10 h-10 bg-orange-600 rounded-lg flex items-center justify-center text-white font-bold text-xl">R</div>
119
+ <span class="text-xl font-extrabold tracking-tight">RUST<span class="text-orange-600">STORE</span></span>
120
+ </div>
121
+ <nav class="hidden md:flex space-x-8 font-medium">
122
+ <a href="#" class="hover:text-orange-600">Каталог</a>
123
+ <a href="#" class="hover:text-orange-600">О нас</a>
124
+ <a href="#" class="hover:text-orange-600">Доставка</a>
125
+ </nav>
126
+ <div class="relative">
127
+ <span class="absolute -top-2 -right-2 bg-orange-600 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">0</span>
128
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
129
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
130
+ </svg>
131
+ </div>
132
+ </div>
133
+ </header>
134
+
135
+ <!-- Hero Section -->
136
+ <main class="max-w-7xl mx-auto px-4 py-12">
137
+ <div class="text-center mb-16">
138
+ <h1 class="text-5xl font-extrabold mb-4">Безопасный шопинг на <span class="text-orange-600">Rust</span></h1>
139
+ <p class="text-gray-500 text-lg">Высокая производительность. Нулевая стоимость абстракций. Красивые товары.</p>
140
+ </div>
141
+
142
+ <!-- Grid -->
143
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
144
+ {cards}
145
+ </div>
146
+ </main>
147
+
148
+ <footer class="mt-20 py-10 border-t border-gray-200 text-center text-gray-400 text-sm">
149
+ <p>&copy; 2024 Powered by Axum & Rust. Работает на Hugging Face Spaces.</p>
150
+ </footer>
151
+ </body>
152
+ </html>
153
+ "#,
154
+ cards = cards_html
155
+ ))
156
  }